diff options
| author | Ryan <fauxpark@gmail.com> | 2024-02-09 22:37:18 +1100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-02-09 22:37:18 +1100 |
| commit | a5ea619139cb08f49cbfa440984ee2604f7104ba (patch) | |
| tree | 3c74866000ad48901829c4bd60ef4b704a130f26 /drivers/led | |
| parent | 137938b67afbf35fd34f2e5cbe3c5c6367a1d0cc (diff) | |
LED drivers: place I2C addresses into an array (#22975)
Diffstat (limited to 'drivers/led')
40 files changed, 1170 insertions, 1242 deletions
diff --git a/drivers/led/issi/is31fl3731-mono.c b/drivers/led/issi/is31fl3731-mono.c index ca4e3449b2..0ffc87765d 100644 --- a/drivers/led/issi/is31fl3731-mono.c +++ b/drivers/led/issi/is31fl3731-mono.c | |||
| @@ -32,6 +32,19 @@ | |||
| 32 | # define IS31FL3731_I2C_PERSISTENCE 0 | 32 | # define IS31FL3731_I2C_PERSISTENCE 0 |
| 33 | #endif | 33 | #endif |
| 34 | 34 | ||
| 35 | const uint8_t i2c_addresses[IS31FL3731_DRIVER_COUNT] = { | ||
| 36 | IS31FL3731_I2C_ADDRESS_1, | ||
| 37 | #ifdef IS31FL3731_I2C_ADDRESS_2 | ||
| 38 | IS31FL3731_I2C_ADDRESS_2, | ||
| 39 | # ifdef IS31FL3731_I2C_ADDRESS_3 | ||
| 40 | IS31FL3731_I2C_ADDRESS_3, | ||
| 41 | # ifdef IS31FL3731_I2C_ADDRESS_4 | ||
| 42 | IS31FL3731_I2C_ADDRESS_4, | ||
| 43 | # endif | ||
| 44 | # endif | ||
| 45 | #endif | ||
| 46 | }; | ||
| 47 | |||
| 35 | // These buffers match the IS31FL3731 PWM registers 0x24-0xB3. | 48 | // These buffers match the IS31FL3731 PWM registers 0x24-0xB3. |
| 36 | // Storing them like this is optimal for I2C transfers to the registers. | 49 | // Storing them like this is optimal for I2C transfers to the registers. |
| 37 | // We could optimize this and take out the unused registers from these | 50 | // We could optimize this and take out the unused registers from these |
| @@ -43,21 +56,21 @@ bool g_pwm_buffer_update_required[IS31FL3731_DRIVER_COUNT] = {false}; | |||
| 43 | uint8_t g_led_control_registers[IS31FL3731_DRIVER_COUNT][IS31FL3731_LED_CONTROL_REGISTER_COUNT] = {0}; | 56 | uint8_t g_led_control_registers[IS31FL3731_DRIVER_COUNT][IS31FL3731_LED_CONTROL_REGISTER_COUNT] = {0}; |
| 44 | bool g_led_control_registers_update_required[IS31FL3731_DRIVER_COUNT] = {false}; | 57 | bool g_led_control_registers_update_required[IS31FL3731_DRIVER_COUNT] = {false}; |
| 45 | 58 | ||
| 46 | void is31fl3731_write_register(uint8_t addr, uint8_t reg, uint8_t data) { | 59 | void is31fl3731_write_register(uint8_t index, uint8_t reg, uint8_t data) { |
| 47 | #if IS31FL3731_I2C_PERSISTENCE > 0 | 60 | #if IS31FL3731_I2C_PERSISTENCE > 0 |
| 48 | for (uint8_t i = 0; i < IS31FL3731_I2C_PERSISTENCE; i++) { | 61 | for (uint8_t i = 0; i < IS31FL3731_I2C_PERSISTENCE; i++) { |
| 49 | if (i2c_write_register(addr << 1, reg, &data, 1, IS31FL3731_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; | 62 | if (i2c_write_register(i2c_addresses[index] << 1, reg, &data, 1, IS31FL3731_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; |
| 50 | } | 63 | } |
| 51 | #else | 64 | #else |
| 52 | i2c_write_register(addr << 1, reg, &data, 1, IS31FL3731_I2C_TIMEOUT); | 65 | i2c_write_register(i2c_addresses[index] << 1, reg, &data, 1, IS31FL3731_I2C_TIMEOUT); |
| 53 | #endif | 66 | #endif |
| 54 | } | 67 | } |
| 55 | 68 | ||
| 56 | void is31fl3731_select_page(uint8_t addr, uint8_t page) { | 69 | void is31fl3731_select_page(uint8_t index, uint8_t page) { |
| 57 | is31fl3731_write_register(addr, IS31FL3731_REG_COMMAND, page); | 70 | is31fl3731_write_register(index, IS31FL3731_REG_COMMAND, page); |
| 58 | } | 71 | } |
| 59 | 72 | ||
| 60 | void is31fl3731_write_pwm_buffer(uint8_t addr, uint8_t index) { | 73 | void is31fl3731_write_pwm_buffer(uint8_t index) { |
| 61 | // Assumes page 0 is already selected. | 74 | // Assumes page 0 is already selected. |
| 62 | // Transmit PWM registers in 9 transfers of 16 bytes. | 75 | // Transmit PWM registers in 9 transfers of 16 bytes. |
| 63 | 76 | ||
| @@ -65,10 +78,10 @@ void is31fl3731_write_pwm_buffer(uint8_t addr, uint8_t index) { | |||
| 65 | for (uint8_t i = 0; i < IS31FL3731_PWM_REGISTER_COUNT; i += 16) { | 78 | for (uint8_t i = 0; i < IS31FL3731_PWM_REGISTER_COUNT; i += 16) { |
| 66 | #if IS31FL3731_I2C_PERSISTENCE > 0 | 79 | #if IS31FL3731_I2C_PERSISTENCE > 0 |
| 67 | for (uint8_t j = 0; j < IS31FL3731_I2C_PERSISTENCE; j++) { | 80 | for (uint8_t j = 0; j < IS31FL3731_I2C_PERSISTENCE; j++) { |
| 68 | if (i2c_write_register(addr << 1, IS31FL3731_FRAME_REG_PWM + i, g_pwm_buffer[index] + i, 16, IS31FL3731_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; | 81 | 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; |
| 69 | } | 82 | } |
| 70 | #else | 83 | #else |
| 71 | i2c_write_register(addr << 1, IS31FL3731_FRAME_REG_PWM + i, g_pwm_buffer[index] + i, 16, IS31FL3731_I2C_TIMEOUT); | 84 | i2c_write_register(i2c_addresses[index] << 1, IS31FL3731_FRAME_REG_PWM + i, g_pwm_buffer[index] + i, 16, IS31FL3731_I2C_TIMEOUT); |
| 72 | #endif | 85 | #endif |
| 73 | } | 86 | } |
| 74 | } | 87 | } |
| @@ -76,83 +89,69 @@ void is31fl3731_write_pwm_buffer(uint8_t addr, uint8_t index) { | |||
| 76 | void is31fl3731_init_drivers(void) { | 89 | void is31fl3731_init_drivers(void) { |
| 77 | i2c_init(); | 90 | i2c_init(); |
| 78 | 91 | ||
| 79 | is31fl3731_init(IS31FL3731_I2C_ADDRESS_1); | 92 | for (uint8_t i = 0; i < IS31FL3731_DRIVER_COUNT; i++) { |
| 80 | #if defined(IS31FL3731_I2C_ADDRESS_2) | 93 | is31fl3731_init(i); |
| 81 | is31fl3731_init(IS31FL3731_I2C_ADDRESS_2); | 94 | } |
| 82 | # if defined(IS31FL3731_I2C_ADDRESS_3) | ||
| 83 | is31fl3731_init(IS31FL3731_I2C_ADDRESS_3); | ||
| 84 | # if defined(IS31FL3731_I2C_ADDRESS_4) | ||
| 85 | is31fl3731_init(IS31FL3731_I2C_ADDRESS_4); | ||
| 86 | # endif | ||
| 87 | # endif | ||
| 88 | #endif | ||
| 89 | 95 | ||
| 90 | for (int i = 0; i < IS31FL3731_LED_COUNT; i++) { | 96 | for (int i = 0; i < IS31FL3731_LED_COUNT; i++) { |
| 91 | is31fl3731_set_led_control_register(i, true); | 97 | is31fl3731_set_led_control_register(i, true); |
| 92 | } | 98 | } |
| 93 | 99 | ||
| 94 | is31fl3731_update_led_control_registers(IS31FL3731_I2C_ADDRESS_1, 0); | 100 | for (uint8_t i = 0; i < IS31FL3731_DRIVER_COUNT; i++) { |
| 95 | #if defined(IS31FL3731_I2C_ADDRESS_2) | 101 | is31fl3731_update_led_control_registers(i); |
| 96 | is31fl3731_update_led_control_registers(IS31FL3731_I2C_ADDRESS_2, 1); | 102 | } |
| 97 | # if defined(IS31FL3731_I2C_ADDRESS_3) | ||
| 98 | is31fl3731_update_led_control_registers(IS31FL3731_I2C_ADDRESS_3, 2); | ||
| 99 | # if defined(IS31FL3731_I2C_ADDRESS_4) | ||
| 100 | is31fl3731_update_led_control_registers(IS31FL3731_I2C_ADDRESS_4, 3); | ||
| 101 | # endif | ||
| 102 | # endif | ||
| 103 | #endif | ||
| 104 | } | 103 | } |
| 105 | 104 | ||
| 106 | void is31fl3731_init(uint8_t addr) { | 105 | void is31fl3731_init(uint8_t index) { |
| 107 | // In order to avoid the LEDs being driven with garbage data | 106 | // In order to avoid the LEDs being driven with garbage data |
| 108 | // in the LED driver's PWM registers, first enable software shutdown, | 107 | // in the LED driver's PWM registers, first enable software shutdown, |
| 109 | // then set up the mode and other settings, clear the PWM registers, | 108 | // then set up the mode and other settings, clear the PWM registers, |
| 110 | // then disable software shutdown. | 109 | // then disable software shutdown. |
| 111 | 110 | ||
| 112 | is31fl3731_select_page(addr, IS31FL3731_COMMAND_FUNCTION); | 111 | is31fl3731_select_page(index, IS31FL3731_COMMAND_FUNCTION); |
| 113 | 112 | ||
| 114 | // enable software shutdown | 113 | // enable software shutdown |
| 115 | is31fl3731_write_register(addr, IS31FL3731_FUNCTION_REG_SHUTDOWN, 0x00); | 114 | is31fl3731_write_register(index, IS31FL3731_FUNCTION_REG_SHUTDOWN, 0x00); |
| 116 | #ifdef IS31FL3731_DEGHOST // set to enable de-ghosting of the array | 115 | #ifdef IS31FL3731_DEGHOST // set to enable de-ghosting of the array |
| 117 | is31fl3731_write_register(addr, IS31FL3731_FUNCTION_REG_GHOST_IMAGE_PREVENTION, IS31FL3731_GHOST_IMAGE_PREVENTION_GEN); | 116 | is31fl3731_write_register(index, IS31FL3731_FUNCTION_REG_GHOST_IMAGE_PREVENTION, IS31FL3731_GHOST_IMAGE_PREVENTION_GEN); |
| 118 | #endif | 117 | #endif |
| 119 | 118 | ||
| 120 | // this delay was copied from other drivers, might not be needed | 119 | // this delay was copied from other drivers, might not be needed |
| 121 | wait_ms(10); | 120 | wait_ms(10); |
| 122 | 121 | ||
| 123 | // picture mode | 122 | // picture mode |
| 124 | is31fl3731_write_register(addr, IS31FL3731_FUNCTION_REG_CONFIG, IS31FL3731_CONFIG_MODE_PICTURE); | 123 | is31fl3731_write_register(index, IS31FL3731_FUNCTION_REG_CONFIG, IS31FL3731_CONFIG_MODE_PICTURE); |
| 125 | // display frame 0 | 124 | // display frame 0 |
| 126 | is31fl3731_write_register(addr, IS31FL3731_FUNCTION_REG_PICTURE_DISPLAY, 0x00); | 125 | is31fl3731_write_register(index, IS31FL3731_FUNCTION_REG_PICTURE_DISPLAY, 0x00); |
| 127 | // audio sync off | 126 | // audio sync off |
| 128 | is31fl3731_write_register(addr, IS31FL3731_FUNCTION_REG_AUDIO_SYNC, 0x00); | 127 | is31fl3731_write_register(index, IS31FL3731_FUNCTION_REG_AUDIO_SYNC, 0x00); |
| 129 | 128 | ||
| 130 | is31fl3731_select_page(addr, IS31FL3731_COMMAND_FRAME_1); | 129 | is31fl3731_select_page(index, IS31FL3731_COMMAND_FRAME_1); |
| 131 | 130 | ||
| 132 | // turn off all LEDs in the LED control register | 131 | // turn off all LEDs in the LED control register |
| 133 | for (uint8_t i = 0; i < IS31FL3731_LED_CONTROL_REGISTER_COUNT; i++) { | 132 | for (uint8_t i = 0; i < IS31FL3731_LED_CONTROL_REGISTER_COUNT; i++) { |
| 134 | is31fl3731_write_register(addr, IS31FL3731_FRAME_REG_LED_CONTROL + i, 0x00); | 133 | is31fl3731_write_register(index, IS31FL3731_FRAME_REG_LED_CONTROL + i, 0x00); |
| 135 | } | 134 | } |
| 136 | 135 | ||
| 137 | // turn off all LEDs in the blink control register (not really needed) | 136 | // turn off all LEDs in the blink control register (not really needed) |
| 138 | for (uint8_t i = 0; i < IS31FL3731_LED_CONTROL_REGISTER_COUNT; i++) { | 137 | for (uint8_t i = 0; i < IS31FL3731_LED_CONTROL_REGISTER_COUNT; i++) { |
| 139 | is31fl3731_write_register(addr, IS31FL3731_FRAME_REG_BLINK_CONTROL + i, 0x00); | 138 | is31fl3731_write_register(index, IS31FL3731_FRAME_REG_BLINK_CONTROL + i, 0x00); |
| 140 | } | 139 | } |
| 141 | 140 | ||
| 142 | // set PWM on all LEDs to 0 | 141 | // set PWM on all LEDs to 0 |
| 143 | for (uint8_t i = 0; i < IS31FL3731_PWM_REGISTER_COUNT; i++) { | 142 | for (uint8_t i = 0; i < IS31FL3731_PWM_REGISTER_COUNT; i++) { |
| 144 | is31fl3731_write_register(addr, IS31FL3731_FRAME_REG_PWM + i, 0x00); | 143 | is31fl3731_write_register(index, IS31FL3731_FRAME_REG_PWM + i, 0x00); |
| 145 | } | 144 | } |
| 146 | 145 | ||
| 147 | is31fl3731_select_page(addr, IS31FL3731_COMMAND_FUNCTION); | 146 | is31fl3731_select_page(index, IS31FL3731_COMMAND_FUNCTION); |
| 148 | 147 | ||
| 149 | // disable software shutdown | 148 | // disable software shutdown |
| 150 | is31fl3731_write_register(addr, IS31FL3731_FUNCTION_REG_SHUTDOWN, 0x01); | 149 | is31fl3731_write_register(index, IS31FL3731_FUNCTION_REG_SHUTDOWN, 0x01); |
| 151 | 150 | ||
| 152 | // select page 0 and leave it selected. | 151 | // select page 0 and leave it selected. |
| 153 | // most usage after initialization is just writing PWM buffers in page 0 | 152 | // most usage after initialization is just writing PWM buffers in page 0 |
| 154 | // as there's not much point in double-buffering | 153 | // as there's not much point in double-buffering |
| 155 | is31fl3731_select_page(addr, IS31FL3731_COMMAND_FRAME_1); | 154 | is31fl3731_select_page(index, IS31FL3731_COMMAND_FRAME_1); |
| 156 | } | 155 | } |
| 157 | 156 | ||
| 158 | void is31fl3731_set_value(int index, uint8_t value) { | 157 | void is31fl3731_set_value(int index, uint8_t value) { |
| @@ -192,18 +191,18 @@ void is31fl3731_set_led_control_register(uint8_t index, bool value) { | |||
| 192 | g_led_control_registers_update_required[led.driver] = true; | 191 | g_led_control_registers_update_required[led.driver] = true; |
| 193 | } | 192 | } |
| 194 | 193 | ||
| 195 | void is31fl3731_update_pwm_buffers(uint8_t addr, uint8_t index) { | 194 | void is31fl3731_update_pwm_buffers(uint8_t index) { |
| 196 | if (g_pwm_buffer_update_required[index]) { | 195 | if (g_pwm_buffer_update_required[index]) { |
| 197 | is31fl3731_write_pwm_buffer(addr, index); | 196 | is31fl3731_write_pwm_buffer(index); |
| 198 | 197 | ||
| 199 | g_pwm_buffer_update_required[index] = false; | 198 | g_pwm_buffer_update_required[index] = false; |
| 200 | } | 199 | } |
| 201 | } | 200 | } |
| 202 | 201 | ||
| 203 | void is31fl3731_update_led_control_registers(uint8_t addr, uint8_t index) { | 202 | void is31fl3731_update_led_control_registers(uint8_t index) { |
| 204 | if (g_led_control_registers_update_required[index]) { | 203 | if (g_led_control_registers_update_required[index]) { |
| 205 | for (uint8_t i = 0; i < IS31FL3731_LED_CONTROL_REGISTER_COUNT; i++) { | 204 | for (uint8_t i = 0; i < IS31FL3731_LED_CONTROL_REGISTER_COUNT; i++) { |
| 206 | is31fl3731_write_register(addr, i, g_led_control_registers[index][i]); | 205 | is31fl3731_write_register(index, i, g_led_control_registers[index][i]); |
| 207 | } | 206 | } |
| 208 | 207 | ||
| 209 | g_led_control_registers_update_required[index] = false; | 208 | g_led_control_registers_update_required[index] = false; |
| @@ -211,14 +210,7 @@ void is31fl3731_update_led_control_registers(uint8_t addr, uint8_t index) { | |||
| 211 | } | 210 | } |
| 212 | 211 | ||
| 213 | void is31fl3731_flush(void) { | 212 | void is31fl3731_flush(void) { |
| 214 | is31fl3731_update_pwm_buffers(IS31FL3731_I2C_ADDRESS_1, 0); | 213 | for (uint8_t i = 0; i < IS31FL3731_DRIVER_COUNT; i++) { |
| 215 | #if defined(IS31FL3731_I2C_ADDRESS_2) | 214 | is31fl3731_update_pwm_buffers(i); |
| 216 | is31fl3731_update_pwm_buffers(IS31FL3731_I2C_ADDRESS_2, 1); | 215 | } |
| 217 | # if defined(IS31FL3731_I2C_ADDRESS_3) | ||
| 218 | is31fl3731_update_pwm_buffers(IS31FL3731_I2C_ADDRESS_3, 2); | ||
| 219 | # if defined(IS31FL3731_I2C_ADDRESS_4) | ||
| 220 | is31fl3731_update_pwm_buffers(IS31FL3731_I2C_ADDRESS_4, 3); | ||
| 221 | # endif | ||
| 222 | # endif | ||
| 223 | #endif | ||
| 224 | } | 216 | } |
diff --git a/drivers/led/issi/is31fl3731-mono.h b/drivers/led/issi/is31fl3731-mono.h index 1b205e0115..e6e107d309 100644 --- a/drivers/led/issi/is31fl3731-mono.h +++ b/drivers/led/issi/is31fl3731-mono.h | |||
| @@ -105,9 +105,9 @@ typedef struct is31fl3731_led_t { | |||
| 105 | extern const is31fl3731_led_t PROGMEM g_is31fl3731_leds[IS31FL3731_LED_COUNT]; | 105 | extern const is31fl3731_led_t PROGMEM g_is31fl3731_leds[IS31FL3731_LED_COUNT]; |
| 106 | 106 | ||
| 107 | void is31fl3731_init_drivers(void); | 107 | void is31fl3731_init_drivers(void); |
| 108 | void is31fl3731_init(uint8_t addr); | 108 | void is31fl3731_init(uint8_t index); |
| 109 | void is31fl3731_write_register(uint8_t addr, uint8_t reg, uint8_t data); | 109 | void is31fl3731_write_register(uint8_t index, uint8_t reg, uint8_t data); |
| 110 | void is31fl3731_select_page(uint8_t addr, uint8_t page); | 110 | void is31fl3731_select_page(uint8_t index, uint8_t page); |
| 111 | 111 | ||
| 112 | void is31fl3731_set_value(int index, uint8_t value); | 112 | void is31fl3731_set_value(int index, uint8_t value); |
| 113 | void is31fl3731_set_value_all(uint8_t value); | 113 | void is31fl3731_set_value_all(uint8_t value); |
| @@ -118,8 +118,8 @@ void is31fl3731_set_led_control_register(uint8_t index, bool value); | |||
| 118 | // (eg. from a timer interrupt). | 118 | // (eg. from a timer interrupt). |
| 119 | // Call this while idle (in between matrix scans). | 119 | // Call this while idle (in between matrix scans). |
| 120 | // If the buffer is dirty, it will update the driver with the buffer. | 120 | // If the buffer is dirty, it will update the driver with the buffer. |
| 121 | void is31fl3731_update_pwm_buffers(uint8_t addr, uint8_t index); | 121 | void is31fl3731_update_pwm_buffers(uint8_t index); |
| 122 | void is31fl3731_update_led_control_registers(uint8_t addr, uint8_t index); | 122 | void is31fl3731_update_led_control_registers(uint8_t index); |
| 123 | 123 | ||
| 124 | void is31fl3731_flush(void); | 124 | void is31fl3731_flush(void); |
| 125 | 125 | ||
diff --git a/drivers/led/issi/is31fl3731.c b/drivers/led/issi/is31fl3731.c index 07f8194c0b..bb6f7e4028 100644 --- a/drivers/led/issi/is31fl3731.c +++ b/drivers/led/issi/is31fl3731.c | |||
| @@ -31,6 +31,19 @@ | |||
| 31 | # define IS31FL3731_I2C_PERSISTENCE 0 | 31 | # define IS31FL3731_I2C_PERSISTENCE 0 |
| 32 | #endif | 32 | #endif |
| 33 | 33 | ||
| 34 | const uint8_t i2c_addresses[IS31FL3731_DRIVER_COUNT] = { | ||
| 35 | IS31FL3731_I2C_ADDRESS_1, | ||
| 36 | #ifdef IS31FL3731_I2C_ADDRESS_2 | ||
| 37 | IS31FL3731_I2C_ADDRESS_2, | ||
| 38 | # ifdef IS31FL3731_I2C_ADDRESS_3 | ||
| 39 | IS31FL3731_I2C_ADDRESS_3, | ||
| 40 | # ifdef IS31FL3731_I2C_ADDRESS_4 | ||
| 41 | IS31FL3731_I2C_ADDRESS_4, | ||
| 42 | # endif | ||
| 43 | # endif | ||
| 44 | #endif | ||
| 45 | }; | ||
| 46 | |||
| 34 | // These buffers match the IS31FL3731 PWM registers 0x24-0xB3. | 47 | // These buffers match the IS31FL3731 PWM registers 0x24-0xB3. |
| 35 | // Storing them like this is optimal for I2C transfers to the registers. | 48 | // Storing them like this is optimal for I2C transfers to the registers. |
| 36 | // We could optimize this and take out the unused registers from these | 49 | // We could optimize this and take out the unused registers from these |
| @@ -42,21 +55,21 @@ bool g_pwm_buffer_update_required[IS31FL3731_DRIVER_COUNT] = {false}; | |||
| 42 | uint8_t g_led_control_registers[IS31FL3731_DRIVER_COUNT][IS31FL3731_LED_CONTROL_REGISTER_COUNT] = {0}; | 55 | uint8_t g_led_control_registers[IS31FL3731_DRIVER_COUNT][IS31FL3731_LED_CONTROL_REGISTER_COUNT] = {0}; |
| 43 | bool g_led_control_registers_update_required[IS31FL3731_DRIVER_COUNT] = {false}; | 56 | bool g_led_control_registers_update_required[IS31FL3731_DRIVER_COUNT] = {false}; |
| 44 | 57 | ||
| 45 | void is31fl3731_write_register(uint8_t addr, uint8_t reg, uint8_t data) { | 58 | void is31fl3731_write_register(uint8_t index, uint8_t reg, uint8_t data) { |
| 46 | #if IS31FL3731_I2C_PERSISTENCE > 0 | 59 | #if IS31FL3731_I2C_PERSISTENCE > 0 |
| 47 | for (uint8_t i = 0; i < IS31FL3731_I2C_PERSISTENCE; i++) { | 60 | for (uint8_t i = 0; i < IS31FL3731_I2C_PERSISTENCE; i++) { |
| 48 | if (i2c_write_register(addr << 1, reg, &data, 1, IS31FL3731_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; | 61 | if (i2c_write_register(i2c_addresses[index] << 1, reg, &data, 1, IS31FL3731_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; |
| 49 | } | 62 | } |
| 50 | #else | 63 | #else |
| 51 | i2c_write_register(addr << 1, reg, &data, 1, IS31FL3731_I2C_TIMEOUT); | 64 | i2c_write_register(i2c_addresses[index] << 1, reg, &data, 1, IS31FL3731_I2C_TIMEOUT); |
| 52 | #endif | 65 | #endif |
| 53 | } | 66 | } |
| 54 | 67 | ||
| 55 | void is31fl3731_select_page(uint8_t addr, uint8_t page) { | 68 | void is31fl3731_select_page(uint8_t index, uint8_t page) { |
| 56 | is31fl3731_write_register(addr, IS31FL3731_REG_COMMAND, page); | 69 | is31fl3731_write_register(index, IS31FL3731_REG_COMMAND, page); |
| 57 | } | 70 | } |
| 58 | 71 | ||
| 59 | void is31fl3731_write_pwm_buffer(uint8_t addr, uint8_t index) { | 72 | void is31fl3731_write_pwm_buffer(uint8_t index) { |
| 60 | // Assumes page 0 is already selected. | 73 | // Assumes page 0 is already selected. |
| 61 | // Transmit PWM registers in 9 transfers of 16 bytes. | 74 | // Transmit PWM registers in 9 transfers of 16 bytes. |
| 62 | 75 | ||
| @@ -64,10 +77,10 @@ void is31fl3731_write_pwm_buffer(uint8_t addr, uint8_t index) { | |||
| 64 | for (uint8_t i = 0; i < IS31FL3731_PWM_REGISTER_COUNT; i += 16) { | 77 | for (uint8_t i = 0; i < IS31FL3731_PWM_REGISTER_COUNT; i += 16) { |
| 65 | #if IS31FL3731_I2C_PERSISTENCE > 0 | 78 | #if IS31FL3731_I2C_PERSISTENCE > 0 |
| 66 | for (uint8_t j = 0; j < IS31FL3731_I2C_PERSISTENCE; j++) { | 79 | for (uint8_t j = 0; j < IS31FL3731_I2C_PERSISTENCE; j++) { |
| 67 | if (i2c_write_register(addr << 1, IS31FL3731_FRAME_REG_PWM + i, g_pwm_buffer[index] + i, 16, IS31FL3731_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; | 80 | 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; |
| 68 | } | 81 | } |
| 69 | #else | 82 | #else |
| 70 | i2c_write_register(addr << 1, IS31FL3731_FRAME_REG_PWM + i, g_pwm_buffer[index] + i, 16, IS31FL3731_I2C_TIMEOUT); | 83 | i2c_write_register(i2c_addresses[index] << 1, IS31FL3731_FRAME_REG_PWM + i, g_pwm_buffer[index] + i, 16, IS31FL3731_I2C_TIMEOUT); |
| 71 | #endif | 84 | #endif |
| 72 | } | 85 | } |
| 73 | } | 86 | } |
| @@ -75,83 +88,69 @@ void is31fl3731_write_pwm_buffer(uint8_t addr, uint8_t index) { | |||
| 75 | void is31fl3731_init_drivers(void) { | 88 | void is31fl3731_init_drivers(void) { |
| 76 | i2c_init(); | 89 | i2c_init(); |
| 77 | 90 | ||
| 78 | is31fl3731_init(IS31FL3731_I2C_ADDRESS_1); | 91 | for (uint8_t i = 0; i < IS31FL3731_DRIVER_COUNT; i++) { |
| 79 | #if defined(IS31FL3731_I2C_ADDRESS_2) | 92 | is31fl3731_init(i); |
| 80 | is31fl3731_init(IS31FL3731_I2C_ADDRESS_2); | 93 | } |
| 81 | # if defined(IS31FL3731_I2C_ADDRESS_3) | ||
| 82 | is31fl3731_init(IS31FL3731_I2C_ADDRESS_3); | ||
| 83 | # if defined(IS31FL3731_I2C_ADDRESS_4) | ||
| 84 | is31fl3731_init(IS31FL3731_I2C_ADDRESS_4); | ||
| 85 | # endif | ||
| 86 | # endif | ||
| 87 | #endif | ||
| 88 | 94 | ||
| 89 | for (int i = 0; i < IS31FL3731_LED_COUNT; i++) { | 95 | for (int i = 0; i < IS31FL3731_LED_COUNT; i++) { |
| 90 | is31fl3731_set_led_control_register(i, true, true, true); | 96 | is31fl3731_set_led_control_register(i, true, true, true); |
| 91 | } | 97 | } |
| 92 | 98 | ||
| 93 | is31fl3731_update_led_control_registers(IS31FL3731_I2C_ADDRESS_1, 0); | 99 | for (uint8_t i = 0; i < IS31FL3731_DRIVER_COUNT; i++) { |
| 94 | #if defined(IS31FL3731_I2C_ADDRESS_2) | 100 | is31fl3731_update_led_control_registers(i); |
| 95 | is31fl3731_update_led_control_registers(IS31FL3731_I2C_ADDRESS_2, 1); | 101 | } |
| 96 | # if defined(IS31FL3731_I2C_ADDRESS_3) | ||
| 97 | is31fl3731_update_led_control_registers(IS31FL3731_I2C_ADDRESS_3, 2); | ||
| 98 | # if defined(IS31FL3731_I2C_ADDRESS_4) | ||
| 99 | is31fl3731_update_led_control_registers(IS31FL3731_I2C_ADDRESS_4, 3); | ||
| 100 | # endif | ||
| 101 | # endif | ||
| 102 | #endif | ||
| 103 | } | 102 | } |
| 104 | 103 | ||
| 105 | void is31fl3731_init(uint8_t addr) { | 104 | void is31fl3731_init(uint8_t index) { |
| 106 | // In order to avoid the LEDs being driven with garbage data | 105 | // In order to avoid the LEDs being driven with garbage data |
| 107 | // in the LED driver's PWM registers, first enable software shutdown, | 106 | // in the LED driver's PWM registers, first enable software shutdown, |
| 108 | // then set up the mode and other settings, clear the PWM registers, | 107 | // then set up the mode and other settings, clear the PWM registers, |
| 109 | // then disable software shutdown. | 108 | // then disable software shutdown. |
| 110 | 109 | ||
| 111 | is31fl3731_select_page(addr, IS31FL3731_COMMAND_FUNCTION); | 110 | is31fl3731_select_page(index, IS31FL3731_COMMAND_FUNCTION); |
| 112 | 111 | ||
| 113 | // enable software shutdown | 112 | // enable software shutdown |
| 114 | is31fl3731_write_register(addr, IS31FL3731_FUNCTION_REG_SHUTDOWN, 0x00); | 113 | is31fl3731_write_register(index, IS31FL3731_FUNCTION_REG_SHUTDOWN, 0x00); |
| 115 | #ifdef IS31FL3731_DEGHOST // set to enable de-ghosting of the array | 114 | #ifdef IS31FL3731_DEGHOST // set to enable de-ghosting of the array |
| 116 | is31fl3731_write_register(addr, IS31FL3731_FUNCTION_REG_GHOST_IMAGE_PREVENTION, IS31FL3731_GHOST_IMAGE_PREVENTION_GEN); | 115 | is31fl3731_write_register(index, IS31FL3731_FUNCTION_REG_GHOST_IMAGE_PREVENTION, IS31FL3731_GHOST_IMAGE_PREVENTION_GEN); |
| 117 | #endif | 116 | #endif |
| 118 | 117 | ||
| 119 | // this delay was copied from other drivers, might not be needed | 118 | // this delay was copied from other drivers, might not be needed |
| 120 | wait_ms(10); | 119 | wait_ms(10); |
| 121 | 120 | ||
| 122 | // picture mode | 121 | // picture mode |
| 123 | is31fl3731_write_register(addr, IS31FL3731_FUNCTION_REG_CONFIG, IS31FL3731_CONFIG_MODE_PICTURE); | 122 | is31fl3731_write_register(index, IS31FL3731_FUNCTION_REG_CONFIG, IS31FL3731_CONFIG_MODE_PICTURE); |
| 124 | // display frame 0 | 123 | // display frame 0 |
| 125 | is31fl3731_write_register(addr, IS31FL3731_FUNCTION_REG_PICTURE_DISPLAY, 0x00); | 124 | is31fl3731_write_register(index, IS31FL3731_FUNCTION_REG_PICTURE_DISPLAY, 0x00); |
| 126 | // audio sync off | 125 | // audio sync off |
| 127 | is31fl3731_write_register(addr, IS31FL3731_FUNCTION_REG_AUDIO_SYNC, 0x00); | 126 | is31fl3731_write_register(index, IS31FL3731_FUNCTION_REG_AUDIO_SYNC, 0x00); |
| 128 | 127 | ||
| 129 | is31fl3731_select_page(addr, IS31FL3731_COMMAND_FRAME_1); | 128 | is31fl3731_select_page(index, IS31FL3731_COMMAND_FRAME_1); |
| 130 | 129 | ||
| 131 | // turn off all LEDs in the LED control register | 130 | // turn off all LEDs in the LED control register |
| 132 | for (uint8_t i = 0; i < IS31FL3731_LED_CONTROL_REGISTER_COUNT; i++) { | 131 | for (uint8_t i = 0; i < IS31FL3731_LED_CONTROL_REGISTER_COUNT; i++) { |
| 133 | is31fl3731_write_register(addr, IS31FL3731_FRAME_REG_LED_CONTROL + i, 0x00); | 132 | is31fl3731_write_register(index, IS31FL3731_FRAME_REG_LED_CONTROL + i, 0x00); |
| 134 | } | 133 | } |
| 135 | 134 | ||
| 136 | // turn off all LEDs in the blink control register (not really needed) | 135 | // turn off all LEDs in the blink control register (not really needed) |
| 137 | for (uint8_t i = 0; i < IS31FL3731_LED_CONTROL_REGISTER_COUNT; i++) { | 136 | for (uint8_t i = 0; i < IS31FL3731_LED_CONTROL_REGISTER_COUNT; i++) { |
| 138 | is31fl3731_write_register(addr, IS31FL3731_FRAME_REG_BLINK_CONTROL + i, 0x00); | 137 | is31fl3731_write_register(index, IS31FL3731_FRAME_REG_BLINK_CONTROL + i, 0x00); |
| 139 | } | 138 | } |
| 140 | 139 | ||
| 141 | // set PWM on all LEDs to 0 | 140 | // set PWM on all LEDs to 0 |
| 142 | for (uint8_t i = 0; i < IS31FL3731_PWM_REGISTER_COUNT; i++) { | 141 | for (uint8_t i = 0; i < IS31FL3731_PWM_REGISTER_COUNT; i++) { |
| 143 | is31fl3731_write_register(addr, IS31FL3731_FRAME_REG_PWM + i, 0x00); | 142 | is31fl3731_write_register(index, IS31FL3731_FRAME_REG_PWM + i, 0x00); |
| 144 | } | 143 | } |
| 145 | 144 | ||
| 146 | is31fl3731_select_page(addr, IS31FL3731_COMMAND_FUNCTION); | 145 | is31fl3731_select_page(index, IS31FL3731_COMMAND_FUNCTION); |
| 147 | 146 | ||
| 148 | // disable software shutdown | 147 | // disable software shutdown |
| 149 | is31fl3731_write_register(addr, IS31FL3731_FUNCTION_REG_SHUTDOWN, 0x01); | 148 | is31fl3731_write_register(index, IS31FL3731_FUNCTION_REG_SHUTDOWN, 0x01); |
| 150 | 149 | ||
| 151 | // select page 0 and leave it selected. | 150 | // select page 0 and leave it selected. |
| 152 | // most usage after initialization is just writing PWM buffers in page 0 | 151 | // most usage after initialization is just writing PWM buffers in page 0 |
| 153 | // as there's not much point in double-buffering | 152 | // as there's not much point in double-buffering |
| 154 | is31fl3731_select_page(addr, IS31FL3731_COMMAND_FRAME_1); | 153 | is31fl3731_select_page(index, IS31FL3731_COMMAND_FRAME_1); |
| 155 | } | 154 | } |
| 156 | 155 | ||
| 157 | void is31fl3731_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { | 156 | void is31fl3731_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { |
| @@ -207,18 +206,18 @@ void is31fl3731_set_led_control_register(uint8_t index, bool red, bool green, bo | |||
| 207 | g_led_control_registers_update_required[led.driver] = true; | 206 | g_led_control_registers_update_required[led.driver] = true; |
| 208 | } | 207 | } |
| 209 | 208 | ||
| 210 | void is31fl3731_update_pwm_buffers(uint8_t addr, uint8_t index) { | 209 | void is31fl3731_update_pwm_buffers(uint8_t index) { |
| 211 | if (g_pwm_buffer_update_required[index]) { | 210 | if (g_pwm_buffer_update_required[index]) { |
| 212 | is31fl3731_write_pwm_buffer(addr, index); | 211 | is31fl3731_write_pwm_buffer(index); |
| 213 | 212 | ||
| 214 | g_pwm_buffer_update_required[index] = false; | 213 | g_pwm_buffer_update_required[index] = false; |
| 215 | } | 214 | } |
| 216 | } | 215 | } |
| 217 | 216 | ||
| 218 | void is31fl3731_update_led_control_registers(uint8_t addr, uint8_t index) { | 217 | void is31fl3731_update_led_control_registers(uint8_t index) { |
| 219 | if (g_led_control_registers_update_required[index]) { | 218 | if (g_led_control_registers_update_required[index]) { |
| 220 | for (uint8_t i = 0; i < IS31FL3731_LED_CONTROL_REGISTER_COUNT; i++) { | 219 | for (uint8_t i = 0; i < IS31FL3731_LED_CONTROL_REGISTER_COUNT; i++) { |
| 221 | is31fl3731_write_register(addr, i, g_led_control_registers[index][i]); | 220 | is31fl3731_write_register(index, i, g_led_control_registers[index][i]); |
| 222 | } | 221 | } |
| 223 | 222 | ||
| 224 | g_led_control_registers_update_required[index] = false; | 223 | g_led_control_registers_update_required[index] = false; |
| @@ -226,14 +225,7 @@ void is31fl3731_update_led_control_registers(uint8_t addr, uint8_t index) { | |||
| 226 | } | 225 | } |
| 227 | 226 | ||
| 228 | void is31fl3731_flush(void) { | 227 | void is31fl3731_flush(void) { |
| 229 | is31fl3731_update_pwm_buffers(IS31FL3731_I2C_ADDRESS_1, 0); | 228 | for (uint8_t i = 0; i < IS31FL3731_DRIVER_COUNT; i++) { |
| 230 | #if defined(IS31FL3731_I2C_ADDRESS_2) | 229 | is31fl3731_update_pwm_buffers(i); |
| 231 | is31fl3731_update_pwm_buffers(IS31FL3731_I2C_ADDRESS_2, 1); | 230 | } |
| 232 | # if defined(IS31FL3731_I2C_ADDRESS_3) | ||
| 233 | is31fl3731_update_pwm_buffers(IS31FL3731_I2C_ADDRESS_3, 2); | ||
| 234 | # if defined(IS31FL3731_I2C_ADDRESS_4) | ||
| 235 | is31fl3731_update_pwm_buffers(IS31FL3731_I2C_ADDRESS_4, 3); | ||
| 236 | # endif | ||
| 237 | # endif | ||
| 238 | #endif | ||
| 239 | } | 231 | } |
diff --git a/drivers/led/issi/is31fl3731.h b/drivers/led/issi/is31fl3731.h index 71cf38db4d..dc229c876d 100644 --- a/drivers/led/issi/is31fl3731.h +++ b/drivers/led/issi/is31fl3731.h | |||
| @@ -106,9 +106,9 @@ typedef struct is31fl3731_led_t { | |||
| 106 | extern const is31fl3731_led_t PROGMEM g_is31fl3731_leds[IS31FL3731_LED_COUNT]; | 106 | extern const is31fl3731_led_t PROGMEM g_is31fl3731_leds[IS31FL3731_LED_COUNT]; |
| 107 | 107 | ||
| 108 | void is31fl3731_init_drivers(void); | 108 | void is31fl3731_init_drivers(void); |
| 109 | void is31fl3731_init(uint8_t addr); | 109 | void is31fl3731_init(uint8_t index); |
| 110 | void is31fl3731_write_register(uint8_t addr, uint8_t reg, uint8_t data); | 110 | void is31fl3731_write_register(uint8_t index, uint8_t reg, uint8_t data); |
| 111 | void is31fl3731_select_page(uint8_t addr, uint8_t page); | 111 | void is31fl3731_select_page(uint8_t index, uint8_t page); |
| 112 | 112 | ||
| 113 | void is31fl3731_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); | 113 | void is31fl3731_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); |
| 114 | void is31fl3731_set_color_all(uint8_t red, uint8_t green, uint8_t blue); | 114 | void is31fl3731_set_color_all(uint8_t red, uint8_t green, uint8_t blue); |
| @@ -119,8 +119,8 @@ void is31fl3731_set_led_control_register(uint8_t index, bool red, bool green, bo | |||
| 119 | // (eg. from a timer interrupt). | 119 | // (eg. from a timer interrupt). |
| 120 | // Call this while idle (in between matrix scans). | 120 | // Call this while idle (in between matrix scans). |
| 121 | // If the buffer is dirty, it will update the driver with the buffer. | 121 | // If the buffer is dirty, it will update the driver with the buffer. |
| 122 | void is31fl3731_update_pwm_buffers(uint8_t addr, uint8_t index); | 122 | void is31fl3731_update_pwm_buffers(uint8_t index); |
| 123 | void is31fl3731_update_led_control_registers(uint8_t addr, uint8_t index); | 123 | void is31fl3731_update_led_control_registers(uint8_t index); |
| 124 | 124 | ||
| 125 | void is31fl3731_flush(void); | 125 | void is31fl3731_flush(void); |
| 126 | 126 | ||
diff --git a/drivers/led/issi/is31fl3733-mono.c b/drivers/led/issi/is31fl3733-mono.c index fe8419e2bc..bbe799bc90 100644 --- a/drivers/led/issi/is31fl3733-mono.c +++ b/drivers/led/issi/is31fl3733-mono.c | |||
| @@ -62,6 +62,32 @@ | |||
| 62 | # define IS31FL3733_SYNC_4 IS31FL3733_SYNC_NONE | 62 | # define IS31FL3733_SYNC_4 IS31FL3733_SYNC_NONE |
| 63 | #endif | 63 | #endif |
| 64 | 64 | ||
| 65 | const uint8_t i2c_addresses[IS31FL3733_DRIVER_COUNT] = { | ||
| 66 | IS31FL3733_I2C_ADDRESS_1, | ||
| 67 | #ifdef IS31FL3733_I2C_ADDRESS_2 | ||
| 68 | IS31FL3733_I2C_ADDRESS_2, | ||
| 69 | # ifdef IS31FL3733_I2C_ADDRESS_3 | ||
| 70 | IS31FL3733_I2C_ADDRESS_3, | ||
| 71 | # ifdef IS31FL3733_I2C_ADDRESS_4 | ||
| 72 | IS31FL3733_I2C_ADDRESS_4, | ||
| 73 | # endif | ||
| 74 | # endif | ||
| 75 | #endif | ||
| 76 | }; | ||
| 77 | |||
| 78 | const uint8_t driver_sync[IS31FL3733_DRIVER_COUNT] = { | ||
| 79 | IS31FL3733_SYNC_1, | ||
| 80 | #ifdef IS31FL3733_I2C_ADDRESS_2 | ||
| 81 | IS31FL3733_SYNC_2, | ||
| 82 | # ifdef IS31FL3733_I2C_ADDRESS_3 | ||
| 83 | IS31FL3733_SYNC_3, | ||
| 84 | # ifdef IS31FL3733_I2C_ADDRESS_4 | ||
| 85 | IS31FL3733_SYNC_4, | ||
| 86 | # endif | ||
| 87 | # endif | ||
| 88 | #endif | ||
| 89 | }; | ||
| 90 | |||
| 65 | // These buffers match the IS31FL3733 PWM registers. | 91 | // These buffers match the IS31FL3733 PWM registers. |
| 66 | // The control buffers match the page 0 LED On/Off registers. | 92 | // The control buffers match the page 0 LED On/Off registers. |
| 67 | // Storing them like this is optimal for I2C transfers to the registers. | 93 | // Storing them like this is optimal for I2C transfers to the registers. |
| @@ -74,22 +100,22 @@ bool g_pwm_buffer_update_required[IS31FL3733_DRIVER_COUNT] = {false}; | |||
| 74 | uint8_t g_led_control_registers[IS31FL3733_DRIVER_COUNT][IS31FL3733_LED_CONTROL_REGISTER_COUNT] = {0}; | 100 | uint8_t g_led_control_registers[IS31FL3733_DRIVER_COUNT][IS31FL3733_LED_CONTROL_REGISTER_COUNT] = {0}; |
| 75 | bool g_led_control_registers_update_required[IS31FL3733_DRIVER_COUNT] = {false}; | 101 | bool g_led_control_registers_update_required[IS31FL3733_DRIVER_COUNT] = {false}; |
| 76 | 102 | ||
| 77 | void is31fl3733_write_register(uint8_t addr, uint8_t reg, uint8_t data) { | 103 | void is31fl3733_write_register(uint8_t index, uint8_t reg, uint8_t data) { |
| 78 | #if IS31FL3733_I2C_PERSISTENCE > 0 | 104 | #if IS31FL3733_I2C_PERSISTENCE > 0 |
| 79 | for (uint8_t i = 0; i < IS31FL3733_I2C_PERSISTENCE; i++) { | 105 | for (uint8_t i = 0; i < IS31FL3733_I2C_PERSISTENCE; i++) { |
| 80 | if (i2c_write_register(addr << 1, reg, &data, 1, IS31FL3733_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; | 106 | if (i2c_write_register(i2c_addresses[index] << 1, reg, &data, 1, IS31FL3733_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; |
| 81 | } | 107 | } |
| 82 | #else | 108 | #else |
| 83 | i2c_write_register(addr << 1, reg, &data, 1, IS31FL3733_I2C_TIMEOUT); | 109 | i2c_write_register(i2c_addresses[index] << 1, reg, &data, 1, IS31FL3733_I2C_TIMEOUT); |
| 84 | #endif | 110 | #endif |
| 85 | } | 111 | } |
| 86 | 112 | ||
| 87 | void is31fl3733_select_page(uint8_t addr, uint8_t page) { | 113 | void is31fl3733_select_page(uint8_t index, uint8_t page) { |
| 88 | is31fl3733_write_register(addr, IS31FL3733_REG_COMMAND_WRITE_LOCK, IS31FL3733_COMMAND_WRITE_LOCK_MAGIC); | 114 | is31fl3733_write_register(index, IS31FL3733_REG_COMMAND_WRITE_LOCK, IS31FL3733_COMMAND_WRITE_LOCK_MAGIC); |
| 89 | is31fl3733_write_register(addr, IS31FL3733_REG_COMMAND, page); | 115 | is31fl3733_write_register(index, IS31FL3733_REG_COMMAND, page); |
| 90 | } | 116 | } |
| 91 | 117 | ||
| 92 | void is31fl3733_write_pwm_buffer(uint8_t addr, uint8_t index) { | 118 | void is31fl3733_write_pwm_buffer(uint8_t index) { |
| 93 | // Assumes page 1 is already selected. | 119 | // Assumes page 1 is already selected. |
| 94 | // Transmit PWM registers in 12 transfers of 16 bytes. | 120 | // Transmit PWM registers in 12 transfers of 16 bytes. |
| 95 | 121 | ||
| @@ -97,10 +123,10 @@ void is31fl3733_write_pwm_buffer(uint8_t addr, uint8_t index) { | |||
| 97 | for (uint8_t i = 0; i < IS31FL3733_PWM_REGISTER_COUNT; i += 16) { | 123 | for (uint8_t i = 0; i < IS31FL3733_PWM_REGISTER_COUNT; i += 16) { |
| 98 | #if IS31FL3733_I2C_PERSISTENCE > 0 | 124 | #if IS31FL3733_I2C_PERSISTENCE > 0 |
| 99 | for (uint8_t j = 0; j < IS31FL3733_I2C_PERSISTENCE; j++) { | 125 | for (uint8_t j = 0; j < IS31FL3733_I2C_PERSISTENCE; j++) { |
| 100 | if (i2c_write_register(addr << 1, i, g_pwm_buffer[index] + i, 16, IS31FL3733_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; | 126 | if (i2c_write_register(i2c_addresses[index] << 1, i, g_pwm_buffer[index] + i, 16, IS31FL3733_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; |
| 101 | } | 127 | } |
| 102 | #else | 128 | #else |
| 103 | i2c_write_register(addr << 1, i, g_pwm_buffer[index] + i, 16, IS31FL3733_I2C_TIMEOUT); | 129 | i2c_write_register(i2c_addresses[index] << 1, i, g_pwm_buffer[index] + i, 16, IS31FL3733_I2C_TIMEOUT); |
| 104 | #endif | 130 | #endif |
| 105 | } | 131 | } |
| 106 | } | 132 | } |
| @@ -108,65 +134,52 @@ void is31fl3733_write_pwm_buffer(uint8_t addr, uint8_t index) { | |||
| 108 | void is31fl3733_init_drivers(void) { | 134 | void is31fl3733_init_drivers(void) { |
| 109 | i2c_init(); | 135 | i2c_init(); |
| 110 | 136 | ||
| 111 | is31fl3733_init(IS31FL3733_I2C_ADDRESS_1, IS31FL3733_SYNC_1); | 137 | for (uint8_t i = 0; i < IS31FL3733_DRIVER_COUNT; i++) { |
| 112 | #if defined(IS31FL3733_I2C_ADDRESS_2) | 138 | is31fl3733_init(i); |
| 113 | is31fl3733_init(IS31FL3733_I2C_ADDRESS_2, IS31FL3733_SYNC_2); | 139 | } |
| 114 | # if defined(IS31FL3733_I2C_ADDRESS_3) | ||
| 115 | is31fl3733_init(IS31FL3733_I2C_ADDRESS_3, IS31FL3733_SYNC_3); | ||
| 116 | # if defined(IS31FL3733_I2C_ADDRESS_4) | ||
| 117 | is31fl3733_init(IS31FL3733_I2C_ADDRESS_4, IS31FL3733_SYNC_4); | ||
| 118 | # endif | ||
| 119 | # endif | ||
| 120 | #endif | ||
| 121 | 140 | ||
| 122 | for (int i = 0; i < IS31FL3733_LED_COUNT; i++) { | 141 | for (int i = 0; i < IS31FL3733_LED_COUNT; i++) { |
| 123 | is31fl3733_set_led_control_register(i, true); | 142 | is31fl3733_set_led_control_register(i, true); |
| 124 | } | 143 | } |
| 125 | 144 | ||
| 126 | is31fl3733_update_led_control_registers(IS31FL3733_I2C_ADDRESS_1, 0); | 145 | for (uint8_t i = 0; i < IS31FL3733_DRIVER_COUNT; i++) { |
| 127 | #if defined(IS31FL3733_I2C_ADDRESS_2) | 146 | is31fl3733_update_led_control_registers(i); |
| 128 | is31fl3733_update_led_control_registers(IS31FL3733_I2C_ADDRESS_2, 1); | 147 | } |
| 129 | # if defined(IS31FL3733_I2C_ADDRESS_3) | ||
| 130 | is31fl3733_update_led_control_registers(IS31FL3733_I2C_ADDRESS_3, 2); | ||
| 131 | # if defined(IS31FL3733_I2C_ADDRESS_4) | ||
| 132 | is31fl3733_update_led_control_registers(IS31FL3733_I2C_ADDRESS_4, 3); | ||
| 133 | # endif | ||
| 134 | # endif | ||
| 135 | #endif | ||
| 136 | } | 148 | } |
| 137 | 149 | ||
| 138 | void is31fl3733_init(uint8_t addr, uint8_t sync) { | 150 | void is31fl3733_init(uint8_t index) { |
| 139 | // In order to avoid the LEDs being driven with garbage data | 151 | // In order to avoid the LEDs being driven with garbage data |
| 140 | // in the LED driver's PWM registers, shutdown is enabled last. | 152 | // in the LED driver's PWM registers, shutdown is enabled last. |
| 141 | // Set up the mode and other settings, clear the PWM registers, | 153 | // Set up the mode and other settings, clear the PWM registers, |
| 142 | // then disable software shutdown. | 154 | // then disable software shutdown. |
| 143 | // Sync is passed so set it according to the datasheet. | ||
| 144 | 155 | ||
| 145 | is31fl3733_select_page(addr, IS31FL3733_COMMAND_LED_CONTROL); | 156 | is31fl3733_select_page(index, IS31FL3733_COMMAND_LED_CONTROL); |
| 146 | 157 | ||
| 147 | // Turn off all LEDs. | 158 | // Turn off all LEDs. |
| 148 | for (uint8_t i = 0; i < IS31FL3733_LED_CONTROL_REGISTER_COUNT; i++) { | 159 | for (uint8_t i = 0; i < IS31FL3733_LED_CONTROL_REGISTER_COUNT; i++) { |
| 149 | is31fl3733_write_register(addr, i, 0x00); | 160 | is31fl3733_write_register(index, i, 0x00); |
| 150 | } | 161 | } |
| 151 | 162 | ||
| 152 | is31fl3733_select_page(addr, IS31FL3733_COMMAND_PWM); | 163 | is31fl3733_select_page(index, IS31FL3733_COMMAND_PWM); |
| 153 | 164 | ||
| 154 | // Set PWM on all LEDs to 0 | 165 | // Set PWM on all LEDs to 0 |
| 155 | // No need to setup Breath registers to PWM as that is the default. | 166 | // No need to setup Breath registers to PWM as that is the default. |
| 156 | for (uint8_t i = 0; i < IS31FL3733_PWM_REGISTER_COUNT; i++) { | 167 | for (uint8_t i = 0; i < IS31FL3733_PWM_REGISTER_COUNT; i++) { |
| 157 | is31fl3733_write_register(addr, i, 0x00); | 168 | is31fl3733_write_register(index, i, 0x00); |
| 158 | } | 169 | } |
| 159 | 170 | ||
| 160 | is31fl3733_select_page(addr, IS31FL3733_COMMAND_FUNCTION); | 171 | is31fl3733_select_page(index, IS31FL3733_COMMAND_FUNCTION); |
| 172 | |||
| 173 | uint8_t sync = driver_sync[index]; | ||
| 161 | 174 | ||
| 162 | // Set de-ghost pull-up resistors (SWx) | 175 | // Set de-ghost pull-up resistors (SWx) |
| 163 | is31fl3733_write_register(addr, IS31FL3733_FUNCTION_REG_SW_PULLUP, IS31FL3733_SW_PULLUP); | 176 | is31fl3733_write_register(index, IS31FL3733_FUNCTION_REG_SW_PULLUP, IS31FL3733_SW_PULLUP); |
| 164 | // Set de-ghost pull-down resistors (CSx) | 177 | // Set de-ghost pull-down resistors (CSx) |
| 165 | is31fl3733_write_register(addr, IS31FL3733_FUNCTION_REG_CS_PULLDOWN, IS31FL3733_CS_PULLDOWN); | 178 | is31fl3733_write_register(index, IS31FL3733_FUNCTION_REG_CS_PULLDOWN, IS31FL3733_CS_PULLDOWN); |
| 166 | // Set global current to maximum. | 179 | // Set global current to maximum. |
| 167 | is31fl3733_write_register(addr, IS31FL3733_FUNCTION_REG_GLOBAL_CURRENT, IS31FL3733_GLOBAL_CURRENT); | 180 | is31fl3733_write_register(index, IS31FL3733_FUNCTION_REG_GLOBAL_CURRENT, IS31FL3733_GLOBAL_CURRENT); |
| 168 | // Disable software shutdown. | 181 | // Disable software shutdown. |
| 169 | is31fl3733_write_register(addr, IS31FL3733_FUNCTION_REG_CONFIGURATION, ((sync & 0b11) << 6) | ((IS31FL3733_PWM_FREQUENCY & 0b111) << 3) | 0x01); | 182 | is31fl3733_write_register(index, IS31FL3733_FUNCTION_REG_CONFIGURATION, ((sync & 0b11) << 6) | ((IS31FL3733_PWM_FREQUENCY & 0b111) << 3) | 0x01); |
| 170 | 183 | ||
| 171 | // Wait 10ms to ensure the device has woken up. | 184 | // Wait 10ms to ensure the device has woken up. |
| 172 | wait_ms(10); | 185 | wait_ms(10); |
| @@ -209,22 +222,22 @@ void is31fl3733_set_led_control_register(uint8_t index, bool value) { | |||
| 209 | g_led_control_registers_update_required[led.driver] = true; | 222 | g_led_control_registers_update_required[led.driver] = true; |
| 210 | } | 223 | } |
| 211 | 224 | ||
| 212 | void is31fl3733_update_pwm_buffers(uint8_t addr, uint8_t index) { | 225 | void is31fl3733_update_pwm_buffers(uint8_t index) { |
| 213 | if (g_pwm_buffer_update_required[index]) { | 226 | if (g_pwm_buffer_update_required[index]) { |
| 214 | is31fl3733_select_page(addr, IS31FL3733_COMMAND_PWM); | 227 | is31fl3733_select_page(index, IS31FL3733_COMMAND_PWM); |
| 215 | 228 | ||
| 216 | is31fl3733_write_pwm_buffer(addr, index); | 229 | is31fl3733_write_pwm_buffer(index); |
| 217 | 230 | ||
| 218 | g_pwm_buffer_update_required[index] = false; | 231 | g_pwm_buffer_update_required[index] = false; |
| 219 | } | 232 | } |
| 220 | } | 233 | } |
| 221 | 234 | ||
| 222 | void is31fl3733_update_led_control_registers(uint8_t addr, uint8_t index) { | 235 | void is31fl3733_update_led_control_registers(uint8_t index) { |
| 223 | if (g_led_control_registers_update_required[index]) { | 236 | if (g_led_control_registers_update_required[index]) { |
| 224 | is31fl3733_select_page(addr, IS31FL3733_COMMAND_LED_CONTROL); | 237 | is31fl3733_select_page(index, IS31FL3733_COMMAND_LED_CONTROL); |
| 225 | 238 | ||
| 226 | for (uint8_t i = 0; i < IS31FL3733_LED_CONTROL_REGISTER_COUNT; i++) { | 239 | for (uint8_t i = 0; i < IS31FL3733_LED_CONTROL_REGISTER_COUNT; i++) { |
| 227 | is31fl3733_write_register(addr, i, g_led_control_registers[index][i]); | 240 | is31fl3733_write_register(index, i, g_led_control_registers[index][i]); |
| 228 | } | 241 | } |
| 229 | 242 | ||
| 230 | g_led_control_registers_update_required[index] = false; | 243 | g_led_control_registers_update_required[index] = false; |
| @@ -232,14 +245,7 @@ void is31fl3733_update_led_control_registers(uint8_t addr, uint8_t index) { | |||
| 232 | } | 245 | } |
| 233 | 246 | ||
| 234 | void is31fl3733_flush(void) { | 247 | void is31fl3733_flush(void) { |
| 235 | is31fl3733_update_pwm_buffers(IS31FL3733_I2C_ADDRESS_1, 0); | 248 | for (uint8_t i = 0; i < IS31FL3733_DRIVER_COUNT; i++) { |
| 236 | #if defined(IS31FL3733_I2C_ADDRESS_2) | 249 | is31fl3733_update_pwm_buffers(i); |
| 237 | is31fl3733_update_pwm_buffers(IS31FL3733_I2C_ADDRESS_2, 1); | 250 | } |
| 238 | # if defined(IS31FL3733_I2C_ADDRESS_3) | ||
| 239 | is31fl3733_update_pwm_buffers(IS31FL3733_I2C_ADDRESS_3, 2); | ||
| 240 | # if defined(IS31FL3733_I2C_ADDRESS_4) | ||
| 241 | is31fl3733_update_pwm_buffers(IS31FL3733_I2C_ADDRESS_4, 3); | ||
| 242 | # endif | ||
| 243 | # endif | ||
| 244 | #endif | ||
| 245 | } | 251 | } |
diff --git a/drivers/led/issi/is31fl3733-mono.h b/drivers/led/issi/is31fl3733-mono.h index 591fca907a..1e88e49ed5 100644 --- a/drivers/led/issi/is31fl3733-mono.h +++ b/drivers/led/issi/is31fl3733-mono.h | |||
| @@ -115,9 +115,9 @@ typedef struct is31fl3733_led_t { | |||
| 115 | extern const is31fl3733_led_t PROGMEM g_is31fl3733_leds[IS31FL3733_LED_COUNT]; | 115 | extern const is31fl3733_led_t PROGMEM g_is31fl3733_leds[IS31FL3733_LED_COUNT]; |
| 116 | 116 | ||
| 117 | void is31fl3733_init_drivers(void); | 117 | void is31fl3733_init_drivers(void); |
| 118 | void is31fl3733_init(uint8_t addr, uint8_t sync); | 118 | void is31fl3733_init(uint8_t index); |
| 119 | void is31fl3733_write_register(uint8_t addr, uint8_t reg, uint8_t data); | 119 | void is31fl3733_write_register(uint8_t index, uint8_t reg, uint8_t data); |
| 120 | void is31fl3733_select_page(uint8_t addr, uint8_t page); | 120 | void is31fl3733_select_page(uint8_t index, uint8_t page); |
| 121 | 121 | ||
| 122 | void is31fl3733_set_value(int index, uint8_t value); | 122 | void is31fl3733_set_value(int index, uint8_t value); |
| 123 | void is31fl3733_set_value_all(uint8_t value); | 123 | void is31fl3733_set_value_all(uint8_t value); |
| @@ -128,8 +128,8 @@ void is31fl3733_set_led_control_register(uint8_t index, bool value); | |||
| 128 | // (eg. from a timer interrupt). | 128 | // (eg. from a timer interrupt). |
| 129 | // Call this while idle (in between matrix scans). | 129 | // Call this while idle (in between matrix scans). |
| 130 | // If the buffer is dirty, it will update the driver with the buffer. | 130 | // If the buffer is dirty, it will update the driver with the buffer. |
| 131 | void is31fl3733_update_pwm_buffers(uint8_t addr, uint8_t index); | 131 | void is31fl3733_update_pwm_buffers(uint8_t index); |
| 132 | void is31fl3733_update_led_control_registers(uint8_t addr, uint8_t index); | 132 | void is31fl3733_update_led_control_registers(uint8_t index); |
| 133 | 133 | ||
| 134 | void is31fl3733_flush(void); | 134 | void is31fl3733_flush(void); |
| 135 | 135 | ||
diff --git a/drivers/led/issi/is31fl3733.c b/drivers/led/issi/is31fl3733.c index a54b9c90ba..9637746d22 100644 --- a/drivers/led/issi/is31fl3733.c +++ b/drivers/led/issi/is31fl3733.c | |||
| @@ -61,6 +61,32 @@ | |||
| 61 | # define IS31FL3733_SYNC_4 IS31FL3733_SYNC_NONE | 61 | # define IS31FL3733_SYNC_4 IS31FL3733_SYNC_NONE |
| 62 | #endif | 62 | #endif |
| 63 | 63 | ||
| 64 | const uint8_t i2c_addresses[IS31FL3733_DRIVER_COUNT] = { | ||
| 65 | IS31FL3733_I2C_ADDRESS_1, | ||
| 66 | #ifdef IS31FL3733_I2C_ADDRESS_2 | ||
| 67 | IS31FL3733_I2C_ADDRESS_2, | ||
| 68 | # ifdef IS31FL3733_I2C_ADDRESS_3 | ||
| 69 | IS31FL3733_I2C_ADDRESS_3, | ||
| 70 | # ifdef IS31FL3733_I2C_ADDRESS_4 | ||
| 71 | IS31FL3733_I2C_ADDRESS_4, | ||
| 72 | # endif | ||
| 73 | # endif | ||
| 74 | #endif | ||
| 75 | }; | ||
| 76 | |||
| 77 | const uint8_t driver_sync[IS31FL3733_DRIVER_COUNT] = { | ||
| 78 | IS31FL3733_SYNC_1, | ||
| 79 | #ifdef IS31FL3733_I2C_ADDRESS_2 | ||
| 80 | IS31FL3733_SYNC_2, | ||
| 81 | # ifdef IS31FL3733_I2C_ADDRESS_3 | ||
| 82 | IS31FL3733_SYNC_3, | ||
| 83 | # ifdef IS31FL3733_I2C_ADDRESS_4 | ||
| 84 | IS31FL3733_SYNC_4, | ||
| 85 | # endif | ||
| 86 | # endif | ||
| 87 | #endif | ||
| 88 | }; | ||
| 89 | |||
| 64 | // These buffers match the IS31FL3733 PWM registers. | 90 | // These buffers match the IS31FL3733 PWM registers. |
| 65 | // The control buffers match the page 0 LED On/Off registers. | 91 | // The control buffers match the page 0 LED On/Off registers. |
| 66 | // Storing them like this is optimal for I2C transfers to the registers. | 92 | // Storing them like this is optimal for I2C transfers to the registers. |
| @@ -73,22 +99,22 @@ bool g_pwm_buffer_update_required[IS31FL3733_DRIVER_COUNT] = {false}; | |||
| 73 | uint8_t g_led_control_registers[IS31FL3733_DRIVER_COUNT][IS31FL3733_LED_CONTROL_REGISTER_COUNT] = {0}; | 99 | uint8_t g_led_control_registers[IS31FL3733_DRIVER_COUNT][IS31FL3733_LED_CONTROL_REGISTER_COUNT] = {0}; |
| 74 | bool g_led_control_registers_update_required[IS31FL3733_DRIVER_COUNT] = {false}; | 100 | bool g_led_control_registers_update_required[IS31FL3733_DRIVER_COUNT] = {false}; |
| 75 | 101 | ||
| 76 | void is31fl3733_write_register(uint8_t addr, uint8_t reg, uint8_t data) { | 102 | void is31fl3733_write_register(uint8_t index, uint8_t reg, uint8_t data) { |
| 77 | #if IS31FL3733_I2C_PERSISTENCE > 0 | 103 | #if IS31FL3733_I2C_PERSISTENCE > 0 |
| 78 | for (uint8_t i = 0; i < IS31FL3733_I2C_PERSISTENCE; i++) { | 104 | for (uint8_t i = 0; i < IS31FL3733_I2C_PERSISTENCE; i++) { |
| 79 | if (i2c_write_register(addr << 1, reg, &data, 1, IS31FL3733_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; | 105 | if (i2c_write_register(i2c_addresses[index] << 1, reg, &data, 1, IS31FL3733_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; |
| 80 | } | 106 | } |
| 81 | #else | 107 | #else |
| 82 | i2c_write_register(addr << 1, reg, &data, 1, IS31FL3733_I2C_TIMEOUT); | 108 | i2c_write_register(i2c_addresses[index] << 1, reg, &data, 1, IS31FL3733_I2C_TIMEOUT); |
| 83 | #endif | 109 | #endif |
| 84 | } | 110 | } |
| 85 | 111 | ||
| 86 | void is31fl3733_select_page(uint8_t addr, uint8_t page) { | 112 | void is31fl3733_select_page(uint8_t index, uint8_t page) { |
| 87 | is31fl3733_write_register(addr, IS31FL3733_REG_COMMAND_WRITE_LOCK, IS31FL3733_COMMAND_WRITE_LOCK_MAGIC); | 113 | is31fl3733_write_register(index, IS31FL3733_REG_COMMAND_WRITE_LOCK, IS31FL3733_COMMAND_WRITE_LOCK_MAGIC); |
| 88 | is31fl3733_write_register(addr, IS31FL3733_REG_COMMAND, page); | 114 | is31fl3733_write_register(index, IS31FL3733_REG_COMMAND, page); |
| 89 | } | 115 | } |
| 90 | 116 | ||
| 91 | void is31fl3733_write_pwm_buffer(uint8_t addr, uint8_t index) { | 117 | void is31fl3733_write_pwm_buffer(uint8_t index) { |
| 92 | // Assumes page 1 is already selected. | 118 | // Assumes page 1 is already selected. |
| 93 | // Transmit PWM registers in 12 transfers of 16 bytes. | 119 | // Transmit PWM registers in 12 transfers of 16 bytes. |
| 94 | 120 | ||
| @@ -96,10 +122,10 @@ void is31fl3733_write_pwm_buffer(uint8_t addr, uint8_t index) { | |||
| 96 | for (uint8_t i = 0; i < IS31FL3733_PWM_REGISTER_COUNT; i += 16) { | 122 | for (uint8_t i = 0; i < IS31FL3733_PWM_REGISTER_COUNT; i += 16) { |
| 97 | #if IS31FL3733_I2C_PERSISTENCE > 0 | 123 | #if IS31FL3733_I2C_PERSISTENCE > 0 |
| 98 | for (uint8_t j = 0; j < IS31FL3733_I2C_PERSISTENCE; j++) { | 124 | for (uint8_t j = 0; j < IS31FL3733_I2C_PERSISTENCE; j++) { |
| 99 | if (i2c_write_register(addr << 1, i, g_pwm_buffer[index] + i, 16, IS31FL3733_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; | 125 | if (i2c_write_register(i2c_addresses[index] << 1, i, g_pwm_buffer[index] + i, 16, IS31FL3733_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; |
| 100 | } | 126 | } |
| 101 | #else | 127 | #else |
| 102 | i2c_write_register(addr << 1, i, g_pwm_buffer[index] + i, 16, IS31FL3733_I2C_TIMEOUT); | 128 | i2c_write_register(i2c_addresses[index] << 1, i, g_pwm_buffer[index] + i, 16, IS31FL3733_I2C_TIMEOUT); |
| 103 | #endif | 129 | #endif |
| 104 | } | 130 | } |
| 105 | } | 131 | } |
| @@ -107,65 +133,52 @@ void is31fl3733_write_pwm_buffer(uint8_t addr, uint8_t index) { | |||
| 107 | void is31fl3733_init_drivers(void) { | 133 | void is31fl3733_init_drivers(void) { |
| 108 | i2c_init(); | 134 | i2c_init(); |
| 109 | 135 | ||
| 110 | is31fl3733_init(IS31FL3733_I2C_ADDRESS_1, IS31FL3733_SYNC_1); | 136 | for (uint8_t i = 0; i < IS31FL3733_DRIVER_COUNT; i++) { |
| 111 | #if defined(IS31FL3733_I2C_ADDRESS_2) | 137 | is31fl3733_init(i); |
| 112 | is31fl3733_init(IS31FL3733_I2C_ADDRESS_2, IS31FL3733_SYNC_2); | 138 | } |
| 113 | # if defined(IS31FL3733_I2C_ADDRESS_3) | ||
| 114 | is31fl3733_init(IS31FL3733_I2C_ADDRESS_3, IS31FL3733_SYNC_3); | ||
| 115 | # if defined(IS31FL3733_I2C_ADDRESS_4) | ||
| 116 | is31fl3733_init(IS31FL3733_I2C_ADDRESS_4, IS31FL3733_SYNC_4); | ||
| 117 | # endif | ||
| 118 | # endif | ||
| 119 | #endif | ||
| 120 | 139 | ||
| 121 | for (int i = 0; i < IS31FL3733_LED_COUNT; i++) { | 140 | for (int i = 0; i < IS31FL3733_LED_COUNT; i++) { |
| 122 | is31fl3733_set_led_control_register(i, true, true, true); | 141 | is31fl3733_set_led_control_register(i, true, true, true); |
| 123 | } | 142 | } |
| 124 | 143 | ||
| 125 | is31fl3733_update_led_control_registers(IS31FL3733_I2C_ADDRESS_1, 0); | 144 | for (uint8_t i = 0; i < IS31FL3733_DRIVER_COUNT; i++) { |
| 126 | #if defined(IS31FL3733_I2C_ADDRESS_2) | 145 | is31fl3733_update_led_control_registers(i); |
| 127 | is31fl3733_update_led_control_registers(IS31FL3733_I2C_ADDRESS_2, 1); | 146 | } |
| 128 | # if defined(IS31FL3733_I2C_ADDRESS_3) | ||
| 129 | is31fl3733_update_led_control_registers(IS31FL3733_I2C_ADDRESS_3, 2); | ||
| 130 | # if defined(IS31FL3733_I2C_ADDRESS_4) | ||
| 131 | is31fl3733_update_led_control_registers(IS31FL3733_I2C_ADDRESS_4, 3); | ||
| 132 | # endif | ||
| 133 | # endif | ||
| 134 | #endif | ||
| 135 | } | 147 | } |
| 136 | 148 | ||
| 137 | void is31fl3733_init(uint8_t addr, uint8_t sync) { | 149 | void is31fl3733_init(uint8_t index) { |
| 138 | // In order to avoid the LEDs being driven with garbage data | 150 | // In order to avoid the LEDs being driven with garbage data |
| 139 | // in the LED driver's PWM registers, shutdown is enabled last. | 151 | // in the LED driver's PWM registers, shutdown is enabled last. |
| 140 | // Set up the mode and other settings, clear the PWM registers, | 152 | // Set up the mode and other settings, clear the PWM registers, |
| 141 | // then disable software shutdown. | 153 | // then disable software shutdown. |
| 142 | // Sync is passed so set it according to the datasheet. | ||
| 143 | 154 | ||
| 144 | is31fl3733_select_page(addr, IS31FL3733_COMMAND_LED_CONTROL); | 155 | is31fl3733_select_page(index, IS31FL3733_COMMAND_LED_CONTROL); |
| 145 | 156 | ||
| 146 | // Turn off all LEDs. | 157 | // Turn off all LEDs. |
| 147 | for (uint8_t i = 0; i < IS31FL3733_LED_CONTROL_REGISTER_COUNT; i++) { | 158 | for (uint8_t i = 0; i < IS31FL3733_LED_CONTROL_REGISTER_COUNT; i++) { |
| 148 | is31fl3733_write_register(addr, i, 0x00); | 159 | is31fl3733_write_register(index, i, 0x00); |
| 149 | } | 160 | } |
| 150 | 161 | ||
| 151 | is31fl3733_select_page(addr, IS31FL3733_COMMAND_PWM); | 162 | is31fl3733_select_page(index, IS31FL3733_COMMAND_PWM); |
| 152 | 163 | ||
| 153 | // Set PWM on all LEDs to 0 | 164 | // Set PWM on all LEDs to 0 |
| 154 | // No need to setup Breath registers to PWM as that is the default. | 165 | // No need to setup Breath registers to PWM as that is the default. |
| 155 | for (uint8_t i = 0; i < IS31FL3733_PWM_REGISTER_COUNT; i++) { | 166 | for (uint8_t i = 0; i < IS31FL3733_PWM_REGISTER_COUNT; i++) { |
| 156 | is31fl3733_write_register(addr, i, 0x00); | 167 | is31fl3733_write_register(index, i, 0x00); |
| 157 | } | 168 | } |
| 158 | 169 | ||
| 159 | is31fl3733_select_page(addr, IS31FL3733_COMMAND_FUNCTION); | 170 | is31fl3733_select_page(index, IS31FL3733_COMMAND_FUNCTION); |
| 171 | |||
| 172 | uint8_t sync = driver_sync[index]; | ||
| 160 | 173 | ||
| 161 | // Set de-ghost pull-up resistors (SWx) | 174 | // Set de-ghost pull-up resistors (SWx) |
| 162 | is31fl3733_write_register(addr, IS31FL3733_FUNCTION_REG_SW_PULLUP, IS31FL3733_SW_PULLUP); | 175 | is31fl3733_write_register(index, IS31FL3733_FUNCTION_REG_SW_PULLUP, IS31FL3733_SW_PULLUP); |
| 163 | // Set de-ghost pull-down resistors (CSx) | 176 | // Set de-ghost pull-down resistors (CSx) |
| 164 | is31fl3733_write_register(addr, IS31FL3733_FUNCTION_REG_CS_PULLDOWN, IS31FL3733_CS_PULLDOWN); | 177 | is31fl3733_write_register(index, IS31FL3733_FUNCTION_REG_CS_PULLDOWN, IS31FL3733_CS_PULLDOWN); |
| 165 | // Set global current to maximum. | 178 | // Set global current to maximum. |
| 166 | is31fl3733_write_register(addr, IS31FL3733_FUNCTION_REG_GLOBAL_CURRENT, IS31FL3733_GLOBAL_CURRENT); | 179 | is31fl3733_write_register(index, IS31FL3733_FUNCTION_REG_GLOBAL_CURRENT, IS31FL3733_GLOBAL_CURRENT); |
| 167 | // Disable software shutdown. | 180 | // Disable software shutdown. |
| 168 | is31fl3733_write_register(addr, IS31FL3733_FUNCTION_REG_CONFIGURATION, ((sync & 0b11) << 6) | ((IS31FL3733_PWM_FREQUENCY & 0b111) << 3) | 0x01); | 181 | is31fl3733_write_register(index, IS31FL3733_FUNCTION_REG_CONFIGURATION, ((sync & 0b11) << 6) | ((IS31FL3733_PWM_FREQUENCY & 0b111) << 3) | 0x01); |
| 169 | 182 | ||
| 170 | // Wait 10ms to ensure the device has woken up. | 183 | // Wait 10ms to ensure the device has woken up. |
| 171 | wait_ms(10); | 184 | wait_ms(10); |
| @@ -224,22 +237,22 @@ void is31fl3733_set_led_control_register(uint8_t index, bool red, bool green, bo | |||
| 224 | g_led_control_registers_update_required[led.driver] = true; | 237 | g_led_control_registers_update_required[led.driver] = true; |
| 225 | } | 238 | } |
| 226 | 239 | ||
| 227 | void is31fl3733_update_pwm_buffers(uint8_t addr, uint8_t index) { | 240 | void is31fl3733_update_pwm_buffers(uint8_t index) { |
| 228 | if (g_pwm_buffer_update_required[index]) { | 241 | if (g_pwm_buffer_update_required[index]) { |
| 229 | is31fl3733_select_page(addr, IS31FL3733_COMMAND_PWM); | 242 | is31fl3733_select_page(index, IS31FL3733_COMMAND_PWM); |
| 230 | 243 | ||
| 231 | is31fl3733_write_pwm_buffer(addr, index); | 244 | is31fl3733_write_pwm_buffer(index); |
| 232 | 245 | ||
| 233 | g_pwm_buffer_update_required[index] = false; | 246 | g_pwm_buffer_update_required[index] = false; |
| 234 | } | 247 | } |
| 235 | } | 248 | } |
| 236 | 249 | ||
| 237 | void is31fl3733_update_led_control_registers(uint8_t addr, uint8_t index) { | 250 | void is31fl3733_update_led_control_registers(uint8_t index) { |
| 238 | if (g_led_control_registers_update_required[index]) { | 251 | if (g_led_control_registers_update_required[index]) { |
| 239 | is31fl3733_select_page(addr, IS31FL3733_COMMAND_LED_CONTROL); | 252 | is31fl3733_select_page(index, IS31FL3733_COMMAND_LED_CONTROL); |
| 240 | 253 | ||
| 241 | for (uint8_t i = 0; i < IS31FL3733_LED_CONTROL_REGISTER_COUNT; i++) { | 254 | for (uint8_t i = 0; i < IS31FL3733_LED_CONTROL_REGISTER_COUNT; i++) { |
| 242 | is31fl3733_write_register(addr, i, g_led_control_registers[index][i]); | 255 | is31fl3733_write_register(index, i, g_led_control_registers[index][i]); |
| 243 | } | 256 | } |
| 244 | 257 | ||
| 245 | g_led_control_registers_update_required[index] = false; | 258 | g_led_control_registers_update_required[index] = false; |
| @@ -247,14 +260,7 @@ void is31fl3733_update_led_control_registers(uint8_t addr, uint8_t index) { | |||
| 247 | } | 260 | } |
| 248 | 261 | ||
| 249 | void is31fl3733_flush(void) { | 262 | void is31fl3733_flush(void) { |
| 250 | is31fl3733_update_pwm_buffers(IS31FL3733_I2C_ADDRESS_1, 0); | 263 | for (uint8_t i = 0; i < IS31FL3733_DRIVER_COUNT; i++) { |
| 251 | #if defined(IS31FL3733_I2C_ADDRESS_2) | 264 | is31fl3733_update_pwm_buffers(i); |
| 252 | is31fl3733_update_pwm_buffers(IS31FL3733_I2C_ADDRESS_2, 1); | 265 | } |
| 253 | # if defined(IS31FL3733_I2C_ADDRESS_3) | ||
| 254 | is31fl3733_update_pwm_buffers(IS31FL3733_I2C_ADDRESS_3, 2); | ||
| 255 | # if defined(IS31FL3733_I2C_ADDRESS_4) | ||
| 256 | is31fl3733_update_pwm_buffers(IS31FL3733_I2C_ADDRESS_4, 3); | ||
| 257 | # endif | ||
| 258 | # endif | ||
| 259 | #endif | ||
| 260 | } | 266 | } |
diff --git a/drivers/led/issi/is31fl3733.h b/drivers/led/issi/is31fl3733.h index 532d35ed57..eef8efc455 100644 --- a/drivers/led/issi/is31fl3733.h +++ b/drivers/led/issi/is31fl3733.h | |||
| @@ -140,9 +140,9 @@ typedef struct is31fl3733_led_t { | |||
| 140 | extern const is31fl3733_led_t PROGMEM g_is31fl3733_leds[IS31FL3733_LED_COUNT]; | 140 | extern const is31fl3733_led_t PROGMEM g_is31fl3733_leds[IS31FL3733_LED_COUNT]; |
| 141 | 141 | ||
| 142 | void is31fl3733_init_drivers(void); | 142 | void is31fl3733_init_drivers(void); |
| 143 | void is31fl3733_init(uint8_t addr, uint8_t sync); | 143 | void is31fl3733_init(uint8_t index); |
| 144 | void is31fl3733_write_register(uint8_t addr, uint8_t reg, uint8_t data); | 144 | void is31fl3733_write_register(uint8_t index, uint8_t reg, uint8_t data); |
| 145 | void is31fl3733_select_page(uint8_t addr, uint8_t page); | 145 | void is31fl3733_select_page(uint8_t index, uint8_t page); |
| 146 | 146 | ||
| 147 | void is31fl3733_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); | 147 | void is31fl3733_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); |
| 148 | void is31fl3733_set_color_all(uint8_t red, uint8_t green, uint8_t blue); | 148 | void is31fl3733_set_color_all(uint8_t red, uint8_t green, uint8_t blue); |
| @@ -153,8 +153,8 @@ void is31fl3733_set_led_control_register(uint8_t index, bool red, bool green, bo | |||
| 153 | // (eg. from a timer interrupt). | 153 | // (eg. from a timer interrupt). |
| 154 | // Call this while idle (in between matrix scans). | 154 | // Call this while idle (in between matrix scans). |
| 155 | // If the buffer is dirty, it will update the driver with the buffer. | 155 | // If the buffer is dirty, it will update the driver with the buffer. |
| 156 | void is31fl3733_update_pwm_buffers(uint8_t addr, uint8_t index); | 156 | void is31fl3733_update_pwm_buffers(uint8_t index); |
| 157 | void is31fl3733_update_led_control_registers(uint8_t addr, uint8_t index); | 157 | void is31fl3733_update_led_control_registers(uint8_t index); |
| 158 | 158 | ||
| 159 | void is31fl3733_flush(void); | 159 | void is31fl3733_flush(void); |
| 160 | 160 | ||
diff --git a/drivers/led/issi/is31fl3736-mono.c b/drivers/led/issi/is31fl3736-mono.c index 2bb83169a4..fa9c520fc6 100644 --- a/drivers/led/issi/is31fl3736-mono.c +++ b/drivers/led/issi/is31fl3736-mono.c | |||
| @@ -46,6 +46,19 @@ | |||
| 46 | # define IS31FL3736_GLOBAL_CURRENT 0xFF | 46 | # define IS31FL3736_GLOBAL_CURRENT 0xFF |
| 47 | #endif | 47 | #endif |
| 48 | 48 | ||
| 49 | const uint8_t i2c_addresses[IS31FL3736_DRIVER_COUNT] = { | ||
| 50 | IS31FL3736_I2C_ADDRESS_1, | ||
| 51 | #ifdef IS31FL3736_I2C_ADDRESS_2 | ||
| 52 | IS31FL3736_I2C_ADDRESS_2, | ||
| 53 | # ifdef IS31FL3736_I2C_ADDRESS_3 | ||
| 54 | IS31FL3736_I2C_ADDRESS_3, | ||
| 55 | # ifdef IS31FL3736_I2C_ADDRESS_4 | ||
| 56 | IS31FL3736_I2C_ADDRESS_4, | ||
| 57 | # endif | ||
| 58 | # endif | ||
| 59 | #endif | ||
| 60 | }; | ||
| 61 | |||
| 49 | // These buffers match the IS31FL3736 PWM registers. | 62 | // These buffers match the IS31FL3736 PWM registers. |
| 50 | // The control buffers match the page 0 LED On/Off registers. | 63 | // The control buffers match the page 0 LED On/Off registers. |
| 51 | // Storing them like this is optimal for I2C transfers to the registers. | 64 | // Storing them like this is optimal for I2C transfers to the registers. |
| @@ -58,22 +71,22 @@ bool g_pwm_buffer_update_required[IS31FL3736_DRIVER_COUNT] = {false}; | |||
| 58 | uint8_t g_led_control_registers[IS31FL3736_DRIVER_COUNT][IS31FL3736_LED_CONTROL_REGISTER_COUNT] = {0}; | 71 | uint8_t g_led_control_registers[IS31FL3736_DRIVER_COUNT][IS31FL3736_LED_CONTROL_REGISTER_COUNT] = {0}; |
| 59 | bool g_led_control_registers_update_required[IS31FL3736_DRIVER_COUNT] = {false}; | 72 | bool g_led_control_registers_update_required[IS31FL3736_DRIVER_COUNT] = {false}; |
| 60 | 73 | ||
| 61 | void is31fl3736_write_register(uint8_t addr, uint8_t reg, uint8_t data) { | 74 | void is31fl3736_write_register(uint8_t index, uint8_t reg, uint8_t data) { |
| 62 | #if IS31FL3736_I2C_PERSISTENCE > 0 | 75 | #if IS31FL3736_I2C_PERSISTENCE > 0 |
| 63 | for (uint8_t i = 0; i < IS31FL3736_I2C_PERSISTENCE; i++) { | 76 | for (uint8_t i = 0; i < IS31FL3736_I2C_PERSISTENCE; i++) { |
| 64 | if (i2c_write_register(addr << 1, reg, &data, 1, IS31FL3736_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; | 77 | if (i2c_write_register(i2c_addresses[index] << 1, reg, &data, 1, IS31FL3736_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; |
| 65 | } | 78 | } |
| 66 | #else | 79 | #else |
| 67 | i2c_write_register(addr << 1, reg, &data, 1, IS31FL3736_I2C_TIMEOUT); | 80 | i2c_write_register(i2c_addresses[index] << 1, reg, &data, 1, IS31FL3736_I2C_TIMEOUT); |
| 68 | #endif | 81 | #endif |
| 69 | } | 82 | } |
| 70 | 83 | ||
| 71 | void is31fl3736_select_page(uint8_t addr, uint8_t page) { | 84 | void is31fl3736_select_page(uint8_t index, uint8_t page) { |
| 72 | is31fl3736_write_register(addr, IS31FL3736_REG_COMMAND_WRITE_LOCK, IS31FL3736_COMMAND_WRITE_LOCK_MAGIC); | 85 | is31fl3736_write_register(index, IS31FL3736_REG_COMMAND_WRITE_LOCK, IS31FL3736_COMMAND_WRITE_LOCK_MAGIC); |
| 73 | is31fl3736_write_register(addr, IS31FL3736_REG_COMMAND, page); | 86 | is31fl3736_write_register(index, IS31FL3736_REG_COMMAND, page); |
| 74 | } | 87 | } |
| 75 | 88 | ||
| 76 | void is31fl3736_write_pwm_buffer(uint8_t addr, uint8_t index) { | 89 | void is31fl3736_write_pwm_buffer(uint8_t index) { |
| 77 | // Assumes page 1 is already selected. | 90 | // Assumes page 1 is already selected. |
| 78 | // Transmit PWM registers in 12 transfers of 16 bytes. | 91 | // Transmit PWM registers in 12 transfers of 16 bytes. |
| 79 | 92 | ||
| @@ -81,10 +94,10 @@ void is31fl3736_write_pwm_buffer(uint8_t addr, uint8_t index) { | |||
| 81 | for (uint8_t i = 0; i < IS31FL3736_PWM_REGISTER_COUNT; i += 16) { | 94 | for (uint8_t i = 0; i < IS31FL3736_PWM_REGISTER_COUNT; i += 16) { |
| 82 | #if IS31FL3736_I2C_PERSISTENCE > 0 | 95 | #if IS31FL3736_I2C_PERSISTENCE > 0 |
| 83 | for (uint8_t j = 0; j < IS31FL3736_I2C_PERSISTENCE; j++) { | 96 | for (uint8_t j = 0; j < IS31FL3736_I2C_PERSISTENCE; j++) { |
| 84 | if (i2c_write_register(addr << 1, i, g_pwm_buffer[index] + i, 16, IS31FL3736_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; | 97 | if (i2c_write_register(i2c_addresses[index] << 1, i, g_pwm_buffer[index] + i, 16, IS31FL3736_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; |
| 85 | } | 98 | } |
| 86 | #else | 99 | #else |
| 87 | i2c_write_register(addr << 1, i, g_pwm_buffer[index] + i, 16, IS31FL3736_I2C_TIMEOUT); | 100 | i2c_write_register(i2c_addresses[index] << 1, i, g_pwm_buffer[index] + i, 16, IS31FL3736_I2C_TIMEOUT); |
| 88 | #endif | 101 | #endif |
| 89 | } | 102 | } |
| 90 | } | 103 | } |
| @@ -92,64 +105,50 @@ void is31fl3736_write_pwm_buffer(uint8_t addr, uint8_t index) { | |||
| 92 | void is31fl3736_init_drivers(void) { | 105 | void is31fl3736_init_drivers(void) { |
| 93 | i2c_init(); | 106 | i2c_init(); |
| 94 | 107 | ||
| 95 | is31fl3736_init(IS31FL3736_I2C_ADDRESS_1); | 108 | for (uint8_t i = 0; i < IS31FL3736_DRIVER_COUNT; i++) { |
| 96 | #if defined(IS31FL3736_I2C_ADDRESS_2) | 109 | is31fl3736_init(i); |
| 97 | is31fl3736_init(IS31FL3736_I2C_ADDRESS_2); | 110 | } |
| 98 | # if defined(IS31FL3736_I2C_ADDRESS_3) | ||
| 99 | is31fl3736_init(IS31FL3736_I2C_ADDRESS_3); | ||
| 100 | # if defined(IS31FL3736_I2C_ADDRESS_4) | ||
| 101 | is31fl3736_init(IS31FL3736_I2C_ADDRESS_4); | ||
| 102 | # endif | ||
| 103 | # endif | ||
| 104 | #endif | ||
| 105 | 111 | ||
| 106 | for (int i = 0; i < IS31FL3736_LED_COUNT; i++) { | 112 | for (int i = 0; i < IS31FL3736_LED_COUNT; i++) { |
| 107 | is31fl3736_set_led_control_register(i, true); | 113 | is31fl3736_set_led_control_register(i, true); |
| 108 | } | 114 | } |
| 109 | 115 | ||
| 110 | is31fl3736_update_led_control_registers(IS31FL3736_I2C_ADDRESS_1, 0); | 116 | for (uint8_t i = 0; i < IS31FL3736_DRIVER_COUNT; i++) { |
| 111 | #if defined(IS31FL3736_I2C_ADDRESS_2) | 117 | is31fl3736_update_led_control_registers(i); |
| 112 | is31fl3736_update_led_control_registers(IS31FL3736_I2C_ADDRESS_2, 1); | 118 | } |
| 113 | # if defined(IS31FL3736_I2C_ADDRESS_3) | ||
| 114 | is31fl3736_update_led_control_registers(IS31FL3736_I2C_ADDRESS_3, 2); | ||
| 115 | # if defined(IS31FL3736_I2C_ADDRESS_4) | ||
| 116 | is31fl3736_update_led_control_registers(IS31FL3736_I2C_ADDRESS_4, 3); | ||
| 117 | # endif | ||
| 118 | # endif | ||
| 119 | #endif | ||
| 120 | } | 119 | } |
| 121 | 120 | ||
| 122 | void is31fl3736_init(uint8_t addr) { | 121 | void is31fl3736_init(uint8_t index) { |
| 123 | // In order to avoid the LEDs being driven with garbage data | 122 | // In order to avoid the LEDs being driven with garbage data |
| 124 | // in the LED driver's PWM registers, shutdown is enabled last. | 123 | // in the LED driver's PWM registers, shutdown is enabled last. |
| 125 | // Set up the mode and other settings, clear the PWM registers, | 124 | // Set up the mode and other settings, clear the PWM registers, |
| 126 | // then disable software shutdown. | 125 | // then disable software shutdown. |
| 127 | 126 | ||
| 128 | is31fl3736_select_page(addr, IS31FL3736_COMMAND_LED_CONTROL); | 127 | is31fl3736_select_page(index, IS31FL3736_COMMAND_LED_CONTROL); |
| 129 | 128 | ||
| 130 | // Turn off all LEDs. | 129 | // Turn off all LEDs. |
| 131 | for (uint8_t i = 0; i < IS31FL3736_LED_CONTROL_REGISTER_COUNT; i++) { | 130 | for (uint8_t i = 0; i < IS31FL3736_LED_CONTROL_REGISTER_COUNT; i++) { |
| 132 | is31fl3736_write_register(addr, i, 0x00); | 131 | is31fl3736_write_register(index, i, 0x00); |
| 133 | } | 132 | } |
| 134 | 133 | ||
| 135 | is31fl3736_select_page(addr, IS31FL3736_COMMAND_PWM); | 134 | is31fl3736_select_page(index, IS31FL3736_COMMAND_PWM); |
| 136 | 135 | ||
| 137 | // Set PWM on all LEDs to 0 | 136 | // Set PWM on all LEDs to 0 |
| 138 | // No need to setup Breath registers to PWM as that is the default. | 137 | // No need to setup Breath registers to PWM as that is the default. |
| 139 | for (uint8_t i = 0; i < IS31FL3736_PWM_REGISTER_COUNT; i++) { | 138 | for (uint8_t i = 0; i < IS31FL3736_PWM_REGISTER_COUNT; i++) { |
| 140 | is31fl3736_write_register(addr, i, 0x00); | 139 | is31fl3736_write_register(index, i, 0x00); |
| 141 | } | 140 | } |
| 142 | 141 | ||
| 143 | is31fl3736_select_page(addr, IS31FL3736_COMMAND_FUNCTION); | 142 | is31fl3736_select_page(index, IS31FL3736_COMMAND_FUNCTION); |
| 144 | 143 | ||
| 145 | // Set de-ghost pull-up resistors (SWx) | 144 | // Set de-ghost pull-up resistors (SWx) |
| 146 | is31fl3736_write_register(addr, IS31FL3736_FUNCTION_REG_SW_PULLUP, IS31FL3736_SW_PULLUP); | 145 | is31fl3736_write_register(index, IS31FL3736_FUNCTION_REG_SW_PULLUP, IS31FL3736_SW_PULLUP); |
| 147 | // Set de-ghost pull-down resistors (CSx) | 146 | // Set de-ghost pull-down resistors (CSx) |
| 148 | is31fl3736_write_register(addr, IS31FL3736_FUNCTION_REG_CS_PULLDOWN, IS31FL3736_CS_PULLDOWN); | 147 | is31fl3736_write_register(index, IS31FL3736_FUNCTION_REG_CS_PULLDOWN, IS31FL3736_CS_PULLDOWN); |
| 149 | // Set global current to maximum. | 148 | // Set global current to maximum. |
| 150 | is31fl3736_write_register(addr, IS31FL3736_FUNCTION_REG_GLOBAL_CURRENT, IS31FL3736_GLOBAL_CURRENT); | 149 | is31fl3736_write_register(index, IS31FL3736_FUNCTION_REG_GLOBAL_CURRENT, IS31FL3736_GLOBAL_CURRENT); |
| 151 | // Disable software shutdown. | 150 | // Disable software shutdown. |
| 152 | is31fl3736_write_register(addr, IS31FL3736_FUNCTION_REG_CONFIGURATION, ((IS31FL3736_PWM_FREQUENCY & 0b111) << 3) | 0x01); | 151 | is31fl3736_write_register(index, IS31FL3736_FUNCTION_REG_CONFIGURATION, ((IS31FL3736_PWM_FREQUENCY & 0b111) << 3) | 0x01); |
| 153 | 152 | ||
| 154 | // Wait 10ms to ensure the device has woken up. | 153 | // Wait 10ms to ensure the device has woken up. |
| 155 | wait_ms(10); | 154 | wait_ms(10); |
| @@ -198,22 +197,22 @@ void is31fl3736_set_led_control_register(uint8_t index, bool value) { | |||
| 198 | g_led_control_registers_update_required[led.driver] = true; | 197 | g_led_control_registers_update_required[led.driver] = true; |
| 199 | } | 198 | } |
| 200 | 199 | ||
| 201 | void is31fl3736_update_pwm_buffers(uint8_t addr, uint8_t index) { | 200 | void is31fl3736_update_pwm_buffers(uint8_t index) { |
| 202 | if (g_pwm_buffer_update_required[index]) { | 201 | if (g_pwm_buffer_update_required[index]) { |
| 203 | is31fl3736_select_page(addr, IS31FL3736_COMMAND_PWM); | 202 | is31fl3736_select_page(index, IS31FL3736_COMMAND_PWM); |
| 204 | 203 | ||
| 205 | is31fl3736_write_pwm_buffer(addr, index); | 204 | is31fl3736_write_pwm_buffer(index); |
| 206 | 205 | ||
| 207 | g_pwm_buffer_update_required[index] = false; | 206 | g_pwm_buffer_update_required[index] = false; |
| 208 | } | 207 | } |
| 209 | } | 208 | } |
| 210 | 209 | ||
| 211 | void is31fl3736_update_led_control_registers(uint8_t addr, uint8_t index) { | 210 | void is31fl3736_update_led_control_registers(uint8_t index) { |
| 212 | if (g_led_control_registers_update_required[index]) { | 211 | if (g_led_control_registers_update_required[index]) { |
| 213 | is31fl3736_select_page(addr, IS31FL3736_COMMAND_LED_CONTROL); | 212 | is31fl3736_select_page(index, IS31FL3736_COMMAND_LED_CONTROL); |
| 214 | 213 | ||
| 215 | for (uint8_t i = 0; i < IS31FL3736_LED_CONTROL_REGISTER_COUNT; i++) { | 214 | for (uint8_t i = 0; i < IS31FL3736_LED_CONTROL_REGISTER_COUNT; i++) { |
| 216 | is31fl3736_write_register(addr, i, g_led_control_registers[index][i]); | 215 | is31fl3736_write_register(index, i, g_led_control_registers[index][i]); |
| 217 | } | 216 | } |
| 218 | 217 | ||
| 219 | g_led_control_registers_update_required[index] = false; | 218 | g_led_control_registers_update_required[index] = false; |
| @@ -221,14 +220,7 @@ void is31fl3736_update_led_control_registers(uint8_t addr, uint8_t index) { | |||
| 221 | } | 220 | } |
| 222 | 221 | ||
| 223 | void is31fl3736_flush(void) { | 222 | void is31fl3736_flush(void) { |
| 224 | is31fl3736_update_pwm_buffers(IS31FL3736_I2C_ADDRESS_1, 0); | 223 | for (uint8_t i = 0; i < IS31FL3736_DRIVER_COUNT; i++) { |
| 225 | #if defined(IS31FL3736_I2C_ADDRESS_2) | 224 | is31fl3736_update_pwm_buffers(i); |
| 226 | is31fl3736_update_pwm_buffers(IS31FL3736_I2C_ADDRESS_2, 1); | 225 | } |
| 227 | # if defined(IS31FL3736_I2C_ADDRESS_3) | ||
| 228 | is31fl3736_update_pwm_buffers(IS31FL3736_I2C_ADDRESS_3, 2); | ||
| 229 | # if defined(IS31FL3736_I2C_ADDRESS_4) | ||
| 230 | is31fl3736_update_pwm_buffers(IS31FL3736_I2C_ADDRESS_4, 3); | ||
| 231 | # endif | ||
| 232 | # endif | ||
| 233 | #endif | ||
| 234 | } | 226 | } |
diff --git a/drivers/led/issi/is31fl3736-mono.h b/drivers/led/issi/is31fl3736-mono.h index 43d1548c02..6571a9ab71 100644 --- a/drivers/led/issi/is31fl3736-mono.h +++ b/drivers/led/issi/is31fl3736-mono.h | |||
| @@ -110,9 +110,9 @@ typedef struct is31fl3736_led_t { | |||
| 110 | extern const is31fl3736_led_t PROGMEM g_is31fl3736_leds[IS31FL3736_LED_COUNT]; | 110 | extern const is31fl3736_led_t PROGMEM g_is31fl3736_leds[IS31FL3736_LED_COUNT]; |
| 111 | 111 | ||
| 112 | void is31fl3736_init_drivers(void); | 112 | void is31fl3736_init_drivers(void); |
| 113 | void is31fl3736_init(uint8_t addr); | 113 | void is31fl3736_init(uint8_t index); |
| 114 | void is31fl3736_write_register(uint8_t addr, uint8_t reg, uint8_t data); | 114 | void is31fl3736_write_register(uint8_t index, uint8_t reg, uint8_t data); |
| 115 | void is31fl3736_select_page(uint8_t addr, uint8_t page); | 115 | void is31fl3736_select_page(uint8_t index, uint8_t page); |
| 116 | 116 | ||
| 117 | void is31fl3736_set_value(int index, uint8_t value); | 117 | void is31fl3736_set_value(int index, uint8_t value); |
| 118 | void is31fl3736_set_value_all(uint8_t value); | 118 | void is31fl3736_set_value_all(uint8_t value); |
| @@ -123,8 +123,8 @@ void is31fl3736_set_led_control_register(uint8_t index, bool value); | |||
| 123 | // (eg. from a timer interrupt). | 123 | // (eg. from a timer interrupt). |
| 124 | // Call this while idle (in between matrix scans). | 124 | // Call this while idle (in between matrix scans). |
| 125 | // If the buffer is dirty, it will update the driver with the buffer. | 125 | // If the buffer is dirty, it will update the driver with the buffer. |
| 126 | void is31fl3736_update_pwm_buffers(uint8_t addr, uint8_t index); | 126 | void is31fl3736_update_pwm_buffers(uint8_t index); |
| 127 | void is31fl3736_update_led_control_registers(uint8_t addr, uint8_t index); | 127 | void is31fl3736_update_led_control_registers(uint8_t index); |
| 128 | 128 | ||
| 129 | void is31fl3736_flush(void); | 129 | void is31fl3736_flush(void); |
| 130 | 130 | ||
diff --git a/drivers/led/issi/is31fl3736.c b/drivers/led/issi/is31fl3736.c index e4cba2c398..b546589693 100644 --- a/drivers/led/issi/is31fl3736.c +++ b/drivers/led/issi/is31fl3736.c | |||
| @@ -46,6 +46,19 @@ | |||
| 46 | # define IS31FL3736_GLOBAL_CURRENT 0xFF | 46 | # define IS31FL3736_GLOBAL_CURRENT 0xFF |
| 47 | #endif | 47 | #endif |
| 48 | 48 | ||
| 49 | const uint8_t i2c_addresses[IS31FL3736_DRIVER_COUNT] = { | ||
| 50 | IS31FL3736_I2C_ADDRESS_1, | ||
| 51 | #ifdef IS31FL3736_I2C_ADDRESS_2 | ||
| 52 | IS31FL3736_I2C_ADDRESS_2, | ||
| 53 | # ifdef IS31FL3736_I2C_ADDRESS_3 | ||
| 54 | IS31FL3736_I2C_ADDRESS_3, | ||
| 55 | # ifdef IS31FL3736_I2C_ADDRESS_4 | ||
| 56 | IS31FL3736_I2C_ADDRESS_4, | ||
| 57 | # endif | ||
| 58 | # endif | ||
| 59 | #endif | ||
| 60 | }; | ||
| 61 | |||
| 49 | // These buffers match the IS31FL3736 PWM registers. | 62 | // These buffers match the IS31FL3736 PWM registers. |
| 50 | // The control buffers match the page 0 LED On/Off registers. | 63 | // The control buffers match the page 0 LED On/Off registers. |
| 51 | // Storing them like this is optimal for I2C transfers to the registers. | 64 | // Storing them like this is optimal for I2C transfers to the registers. |
| @@ -58,22 +71,22 @@ bool g_pwm_buffer_update_required[IS31FL3736_DRIVER_COUNT] = {false}; | |||
| 58 | uint8_t g_led_control_registers[IS31FL3736_DRIVER_COUNT][IS31FL3736_LED_CONTROL_REGISTER_COUNT] = {0}; | 71 | uint8_t g_led_control_registers[IS31FL3736_DRIVER_COUNT][IS31FL3736_LED_CONTROL_REGISTER_COUNT] = {0}; |
| 59 | bool g_led_control_registers_update_required[IS31FL3736_DRIVER_COUNT] = {false}; | 72 | bool g_led_control_registers_update_required[IS31FL3736_DRIVER_COUNT] = {false}; |
| 60 | 73 | ||
| 61 | void is31fl3736_write_register(uint8_t addr, uint8_t reg, uint8_t data) { | 74 | void is31fl3736_write_register(uint8_t index, uint8_t reg, uint8_t data) { |
| 62 | #if IS31FL3736_I2C_PERSISTENCE > 0 | 75 | #if IS31FL3736_I2C_PERSISTENCE > 0 |
| 63 | for (uint8_t i = 0; i < IS31FL3736_I2C_PERSISTENCE; i++) { | 76 | for (uint8_t i = 0; i < IS31FL3736_I2C_PERSISTENCE; i++) { |
| 64 | if (i2c_write_register(addr << 1, reg, &data, 1, IS31FL3736_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; | 77 | if (i2c_write_register(i2c_addresses[index] << 1, reg, &data, 1, IS31FL3736_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; |
| 65 | } | 78 | } |
| 66 | #else | 79 | #else |
| 67 | i2c_write_register(addr << 1, reg, &data, 1, IS31FL3736_I2C_TIMEOUT); | 80 | i2c_write_register(i2c_addresses[index] << 1, reg, &data, 1, IS31FL3736_I2C_TIMEOUT); |
| 68 | #endif | 81 | #endif |
| 69 | } | 82 | } |
| 70 | 83 | ||
| 71 | void is31fl3736_select_page(uint8_t addr, uint8_t page) { | 84 | void is31fl3736_select_page(uint8_t index, uint8_t page) { |
| 72 | is31fl3736_write_register(addr, IS31FL3736_REG_COMMAND_WRITE_LOCK, IS31FL3736_COMMAND_WRITE_LOCK_MAGIC); | 85 | is31fl3736_write_register(index, IS31FL3736_REG_COMMAND_WRITE_LOCK, IS31FL3736_COMMAND_WRITE_LOCK_MAGIC); |
| 73 | is31fl3736_write_register(addr, IS31FL3736_REG_COMMAND, page); | 86 | is31fl3736_write_register(index, IS31FL3736_REG_COMMAND, page); |
| 74 | } | 87 | } |
| 75 | 88 | ||
| 76 | void is31fl3736_write_pwm_buffer(uint8_t addr, uint8_t index) { | 89 | void is31fl3736_write_pwm_buffer(uint8_t index) { |
| 77 | // Assumes page 1 is already selected. | 90 | // Assumes page 1 is already selected. |
| 78 | // Transmit PWM registers in 12 transfers of 16 bytes. | 91 | // Transmit PWM registers in 12 transfers of 16 bytes. |
| 79 | 92 | ||
| @@ -81,10 +94,10 @@ void is31fl3736_write_pwm_buffer(uint8_t addr, uint8_t index) { | |||
| 81 | for (uint8_t i = 0; i < IS31FL3736_PWM_REGISTER_COUNT; i += 16) { | 94 | for (uint8_t i = 0; i < IS31FL3736_PWM_REGISTER_COUNT; i += 16) { |
| 82 | #if IS31FL3736_I2C_PERSISTENCE > 0 | 95 | #if IS31FL3736_I2C_PERSISTENCE > 0 |
| 83 | for (uint8_t j = 0; j < IS31FL3736_I2C_PERSISTENCE; j++) { | 96 | for (uint8_t j = 0; j < IS31FL3736_I2C_PERSISTENCE; j++) { |
| 84 | if (i2c_write_register(addr << 1, i, g_pwm_buffer[index] + i, 16, IS31FL3736_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; | 97 | if (i2c_write_register(i2c_addresses[index] << 1, i, g_pwm_buffer[index] + i, 16, IS31FL3736_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; |
| 85 | } | 98 | } |
| 86 | #else | 99 | #else |
| 87 | i2c_write_register(addr << 1, i, g_pwm_buffer[index] + i, 16, IS31FL3736_I2C_TIMEOUT); | 100 | i2c_write_register(i2c_addresses[index] << 1, i, g_pwm_buffer[index] + i, 16, IS31FL3736_I2C_TIMEOUT); |
| 88 | #endif | 101 | #endif |
| 89 | } | 102 | } |
| 90 | } | 103 | } |
| @@ -92,64 +105,50 @@ void is31fl3736_write_pwm_buffer(uint8_t addr, uint8_t index) { | |||
| 92 | void is31fl3736_init_drivers(void) { | 105 | void is31fl3736_init_drivers(void) { |
| 93 | i2c_init(); | 106 | i2c_init(); |
| 94 | 107 | ||
| 95 | is31fl3736_init(IS31FL3736_I2C_ADDRESS_1); | 108 | for (uint8_t i = 0; i < IS31FL3736_DRIVER_COUNT; i++) { |
| 96 | #if defined(IS31FL3736_I2C_ADDRESS_2) | 109 | is31fl3736_init(i); |
| 97 | is31fl3736_init(IS31FL3736_I2C_ADDRESS_2); | 110 | } |
| 98 | # if defined(IS31FL3736_I2C_ADDRESS_3) | ||
| 99 | is31fl3736_init(IS31FL3736_I2C_ADDRESS_3); | ||
| 100 | # if defined(IS31FL3736_I2C_ADDRESS_4) | ||
| 101 | is31fl3736_init(IS31FL3736_I2C_ADDRESS_4); | ||
| 102 | # endif | ||
| 103 | # endif | ||
| 104 | #endif | ||
| 105 | 111 | ||
| 106 | for (int i = 0; i < IS31FL3736_LED_COUNT; i++) { | 112 | for (int i = 0; i < IS31FL3736_LED_COUNT; i++) { |
| 107 | is31fl3736_set_led_control_register(i, true, true, true); | 113 | is31fl3736_set_led_control_register(i, true, true, true); |
| 108 | } | 114 | } |
| 109 | 115 | ||
| 110 | is31fl3736_update_led_control_registers(IS31FL3736_I2C_ADDRESS_1, 0); | 116 | for (uint8_t i = 0; i < IS31FL3736_DRIVER_COUNT; i++) { |
| 111 | #if defined(IS31FL3736_I2C_ADDRESS_2) | 117 | is31fl3736_update_led_control_registers(i); |
| 112 | is31fl3736_update_led_control_registers(IS31FL3736_I2C_ADDRESS_2, 1); | 118 | } |
| 113 | # if defined(IS31FL3736_I2C_ADDRESS_3) | ||
| 114 | is31fl3736_update_led_control_registers(IS31FL3736_I2C_ADDRESS_3, 2); | ||
| 115 | # if defined(IS31FL3736_I2C_ADDRESS_4) | ||
| 116 | is31fl3736_update_led_control_registers(IS31FL3736_I2C_ADDRESS_4, 3); | ||
| 117 | # endif | ||
| 118 | # endif | ||
| 119 | #endif | ||
| 120 | } | 119 | } |
| 121 | 120 | ||
| 122 | void is31fl3736_init(uint8_t addr) { | 121 | void is31fl3736_init(uint8_t index) { |
| 123 | // In order to avoid the LEDs being driven with garbage data | 122 | // In order to avoid the LEDs being driven with garbage data |
| 124 | // in the LED driver's PWM registers, shutdown is enabled last. | 123 | // in the LED driver's PWM registers, shutdown is enabled last. |
| 125 | // Set up the mode and other settings, clear the PWM registers, | 124 | // Set up the mode and other settings, clear the PWM registers, |
| 126 | // then disable software shutdown. | 125 | // then disable software shutdown. |
| 127 | 126 | ||
| 128 | is31fl3736_select_page(addr, IS31FL3736_COMMAND_LED_CONTROL); | 127 | is31fl3736_select_page(index, IS31FL3736_COMMAND_LED_CONTROL); |
| 129 | 128 | ||
| 130 | // Turn off all LEDs. | 129 | // Turn off all LEDs. |
| 131 | for (uint8_t i = 0; i < IS31FL3736_LED_CONTROL_REGISTER_COUNT; i++) { | 130 | for (uint8_t i = 0; i < IS31FL3736_LED_CONTROL_REGISTER_COUNT; i++) { |
| 132 | is31fl3736_write_register(addr, i, 0x00); | 131 | is31fl3736_write_register(index, i, 0x00); |
| 133 | } | 132 | } |
| 134 | 133 | ||
| 135 | is31fl3736_select_page(addr, IS31FL3736_COMMAND_PWM); | 134 | is31fl3736_select_page(index, IS31FL3736_COMMAND_PWM); |
| 136 | 135 | ||
| 137 | // Set PWM on all LEDs to 0 | 136 | // Set PWM on all LEDs to 0 |
| 138 | // No need to setup Breath registers to PWM as that is the default. | 137 | // No need to setup Breath registers to PWM as that is the default. |
| 139 | for (uint8_t i = 0; i < IS31FL3736_PWM_REGISTER_COUNT; i++) { | 138 | for (uint8_t i = 0; i < IS31FL3736_PWM_REGISTER_COUNT; i++) { |
| 140 | is31fl3736_write_register(addr, i, 0x00); | 139 | is31fl3736_write_register(index, i, 0x00); |
| 141 | } | 140 | } |
| 142 | 141 | ||
| 143 | is31fl3736_select_page(addr, IS31FL3736_COMMAND_FUNCTION); | 142 | is31fl3736_select_page(index, IS31FL3736_COMMAND_FUNCTION); |
| 144 | 143 | ||
| 145 | // Set de-ghost pull-up resistors (SWx) | 144 | // Set de-ghost pull-up resistors (SWx) |
| 146 | is31fl3736_write_register(addr, IS31FL3736_FUNCTION_REG_SW_PULLUP, IS31FL3736_SW_PULLUP); | 145 | is31fl3736_write_register(index, IS31FL3736_FUNCTION_REG_SW_PULLUP, IS31FL3736_SW_PULLUP); |
| 147 | // Set de-ghost pull-down resistors (CSx) | 146 | // Set de-ghost pull-down resistors (CSx) |
| 148 | is31fl3736_write_register(addr, IS31FL3736_FUNCTION_REG_CS_PULLDOWN, IS31FL3736_CS_PULLDOWN); | 147 | is31fl3736_write_register(index, IS31FL3736_FUNCTION_REG_CS_PULLDOWN, IS31FL3736_CS_PULLDOWN); |
| 149 | // Set global current to maximum. | 148 | // Set global current to maximum. |
| 150 | is31fl3736_write_register(addr, IS31FL3736_FUNCTION_REG_GLOBAL_CURRENT, IS31FL3736_GLOBAL_CURRENT); | 149 | is31fl3736_write_register(index, IS31FL3736_FUNCTION_REG_GLOBAL_CURRENT, IS31FL3736_GLOBAL_CURRENT); |
| 151 | // Disable software shutdown. | 150 | // Disable software shutdown. |
| 152 | is31fl3736_write_register(addr, IS31FL3736_FUNCTION_REG_CONFIGURATION, ((IS31FL3736_PWM_FREQUENCY & 0b111) << 3) | 0x01); | 151 | is31fl3736_write_register(index, IS31FL3736_FUNCTION_REG_CONFIGURATION, ((IS31FL3736_PWM_FREQUENCY & 0b111) << 3) | 0x01); |
| 153 | 152 | ||
| 154 | // Wait 10ms to ensure the device has woken up. | 153 | // Wait 10ms to ensure the device has woken up. |
| 155 | wait_ms(10); | 154 | wait_ms(10); |
| @@ -215,22 +214,22 @@ void is31fl3736_set_led_control_register(uint8_t index, bool red, bool green, bo | |||
| 215 | g_led_control_registers_update_required[led.driver] = true; | 214 | g_led_control_registers_update_required[led.driver] = true; |
| 216 | } | 215 | } |
| 217 | 216 | ||
| 218 | void is31fl3736_update_pwm_buffers(uint8_t addr, uint8_t index) { | 217 | void is31fl3736_update_pwm_buffers(uint8_t index) { |
| 219 | if (g_pwm_buffer_update_required[index]) { | 218 | if (g_pwm_buffer_update_required[index]) { |
| 220 | is31fl3736_select_page(addr, IS31FL3736_COMMAND_PWM); | 219 | is31fl3736_select_page(index, IS31FL3736_COMMAND_PWM); |
| 221 | 220 | ||
| 222 | is31fl3736_write_pwm_buffer(addr, index); | 221 | is31fl3736_write_pwm_buffer(index); |
| 223 | 222 | ||
| 224 | g_pwm_buffer_update_required[index] = false; | 223 | g_pwm_buffer_update_required[index] = false; |
| 225 | } | 224 | } |
| 226 | } | 225 | } |
| 227 | 226 | ||
| 228 | void is31fl3736_update_led_control_registers(uint8_t addr, uint8_t index) { | 227 | void is31fl3736_update_led_control_registers(uint8_t index) { |
| 229 | if (g_led_control_registers_update_required[index]) { | 228 | if (g_led_control_registers_update_required[index]) { |
| 230 | is31fl3736_select_page(addr, IS31FL3736_COMMAND_LED_CONTROL); | 229 | is31fl3736_select_page(index, IS31FL3736_COMMAND_LED_CONTROL); |
| 231 | 230 | ||
| 232 | for (uint8_t i = 0; i < IS31FL3736_LED_CONTROL_REGISTER_COUNT; i++) { | 231 | for (uint8_t i = 0; i < IS31FL3736_LED_CONTROL_REGISTER_COUNT; i++) { |
| 233 | is31fl3736_write_register(addr, i, g_led_control_registers[index][i]); | 232 | is31fl3736_write_register(index, i, g_led_control_registers[index][i]); |
| 234 | } | 233 | } |
| 235 | 234 | ||
| 236 | g_led_control_registers_update_required[index] = false; | 235 | g_led_control_registers_update_required[index] = false; |
| @@ -238,14 +237,7 @@ void is31fl3736_update_led_control_registers(uint8_t addr, uint8_t index) { | |||
| 238 | } | 237 | } |
| 239 | 238 | ||
| 240 | void is31fl3736_flush(void) { | 239 | void is31fl3736_flush(void) { |
| 241 | is31fl3736_update_pwm_buffers(IS31FL3736_I2C_ADDRESS_1, 0); | 240 | for (uint8_t i = 0; i < IS31FL3736_DRIVER_COUNT; i++) { |
| 242 | #if defined(IS31FL3736_I2C_ADDRESS_2) | 241 | is31fl3736_update_pwm_buffers(i); |
| 243 | is31fl3736_update_pwm_buffers(IS31FL3736_I2C_ADDRESS_2, 1); | 242 | } |
| 244 | # if defined(IS31FL3736_I2C_ADDRESS_3) | ||
| 245 | is31fl3736_update_pwm_buffers(IS31FL3736_I2C_ADDRESS_3, 2); | ||
| 246 | # if defined(IS31FL3736_I2C_ADDRESS_4) | ||
| 247 | is31fl3736_update_pwm_buffers(IS31FL3736_I2C_ADDRESS_4, 3); | ||
| 248 | # endif | ||
| 249 | # endif | ||
| 250 | #endif | ||
| 251 | } | 243 | } |
diff --git a/drivers/led/issi/is31fl3736.h b/drivers/led/issi/is31fl3736.h index 086edc0e4a..1649048f80 100644 --- a/drivers/led/issi/is31fl3736.h +++ b/drivers/led/issi/is31fl3736.h | |||
| @@ -124,9 +124,9 @@ typedef struct is31fl3736_led_t { | |||
| 124 | extern const is31fl3736_led_t PROGMEM g_is31fl3736_leds[IS31FL3736_LED_COUNT]; | 124 | extern const is31fl3736_led_t PROGMEM g_is31fl3736_leds[IS31FL3736_LED_COUNT]; |
| 125 | 125 | ||
| 126 | void is31fl3736_init_drivers(void); | 126 | void is31fl3736_init_drivers(void); |
| 127 | void is31fl3736_init(uint8_t addr); | 127 | void is31fl3736_init(uint8_t index); |
| 128 | void is31fl3736_write_register(uint8_t addr, uint8_t reg, uint8_t data); | 128 | void is31fl3736_write_register(uint8_t index, uint8_t reg, uint8_t data); |
| 129 | void is31fl3736_select_page(uint8_t addr, uint8_t page); | 129 | void is31fl3736_select_page(uint8_t index, uint8_t page); |
| 130 | 130 | ||
| 131 | void is31fl3736_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); | 131 | void is31fl3736_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); |
| 132 | void is31fl3736_set_color_all(uint8_t red, uint8_t green, uint8_t blue); | 132 | void is31fl3736_set_color_all(uint8_t red, uint8_t green, uint8_t blue); |
| @@ -137,8 +137,8 @@ void is31fl3736_set_led_control_register(uint8_t index, bool red, bool green, bo | |||
| 137 | // (eg. from a timer interrupt). | 137 | // (eg. from a timer interrupt). |
| 138 | // Call this while idle (in between matrix scans). | 138 | // Call this while idle (in between matrix scans). |
| 139 | // If the buffer is dirty, it will update the driver with the buffer. | 139 | // If the buffer is dirty, it will update the driver with the buffer. |
| 140 | void is31fl3736_update_pwm_buffers(uint8_t addr, uint8_t index); | 140 | void is31fl3736_update_pwm_buffers(uint8_t index); |
| 141 | void is31fl3736_update_led_control_registers(uint8_t addr, uint8_t index); | 141 | void is31fl3736_update_led_control_registers(uint8_t index); |
| 142 | 142 | ||
| 143 | void is31fl3736_flush(void); | 143 | void is31fl3736_flush(void); |
| 144 | 144 | ||
diff --git a/drivers/led/issi/is31fl3737-mono.c b/drivers/led/issi/is31fl3737-mono.c index 0e22ea8a6a..f11358b6a3 100644 --- a/drivers/led/issi/is31fl3737-mono.c +++ b/drivers/led/issi/is31fl3737-mono.c | |||
| @@ -48,6 +48,19 @@ | |||
| 48 | # define IS31FL3737_GLOBAL_CURRENT 0xFF | 48 | # define IS31FL3737_GLOBAL_CURRENT 0xFF |
| 49 | #endif | 49 | #endif |
| 50 | 50 | ||
| 51 | const uint8_t i2c_addresses[IS31FL3737_DRIVER_COUNT] = { | ||
| 52 | IS31FL3737_I2C_ADDRESS_1, | ||
| 53 | #ifdef IS31FL3737_I2C_ADDRESS_2 | ||
| 54 | IS31FL3737_I2C_ADDRESS_2, | ||
| 55 | # ifdef IS31FL3737_I2C_ADDRESS_3 | ||
| 56 | IS31FL3737_I2C_ADDRESS_3, | ||
| 57 | # ifdef IS31FL3737_I2C_ADDRESS_4 | ||
| 58 | IS31FL3737_I2C_ADDRESS_4, | ||
| 59 | # endif | ||
| 60 | # endif | ||
| 61 | #endif | ||
| 62 | }; | ||
| 63 | |||
| 51 | // These buffers match the IS31FL3737 PWM registers. | 64 | // These buffers match the IS31FL3737 PWM registers. |
| 52 | // The control buffers match the page 0 LED On/Off registers. | 65 | // The control buffers match the page 0 LED On/Off registers. |
| 53 | // Storing them like this is optimal for I2C transfers to the registers. | 66 | // Storing them like this is optimal for I2C transfers to the registers. |
| @@ -61,22 +74,22 @@ bool g_pwm_buffer_update_required[IS31FL3737_DRIVER_COUNT] = {false}; | |||
| 61 | uint8_t g_led_control_registers[IS31FL3737_DRIVER_COUNT][IS31FL3737_LED_CONTROL_REGISTER_COUNT] = {0}; | 74 | uint8_t g_led_control_registers[IS31FL3737_DRIVER_COUNT][IS31FL3737_LED_CONTROL_REGISTER_COUNT] = {0}; |
| 62 | bool g_led_control_registers_update_required[IS31FL3737_DRIVER_COUNT] = {false}; | 75 | bool g_led_control_registers_update_required[IS31FL3737_DRIVER_COUNT] = {false}; |
| 63 | 76 | ||
| 64 | void is31fl3737_write_register(uint8_t addr, uint8_t reg, uint8_t data) { | 77 | void is31fl3737_write_register(uint8_t index, uint8_t reg, uint8_t data) { |
| 65 | #if IS31FL3737_I2C_PERSISTENCE > 0 | 78 | #if IS31FL3737_I2C_PERSISTENCE > 0 |
| 66 | for (uint8_t i = 0; i < IS31FL3737_I2C_PERSISTENCE; i++) { | 79 | for (uint8_t i = 0; i < IS31FL3737_I2C_PERSISTENCE; i++) { |
| 67 | if (i2c_write_register(addr << 1, reg, &data, 1, IS31FL3737_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; | 80 | if (i2c_write_register(i2c_addresses[index] << 1, reg, &data, 1, IS31FL3737_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; |
| 68 | } | 81 | } |
| 69 | #else | 82 | #else |
| 70 | i2c_write_register(addr << 1, reg, &data, 1, IS31FL3737_I2C_TIMEOUT); | 83 | i2c_write_register(i2c_addresses[index] << 1, reg, &data, 1, IS31FL3737_I2C_TIMEOUT); |
| 71 | #endif | 84 | #endif |
| 72 | } | 85 | } |
| 73 | 86 | ||
| 74 | void is31fl3737_select_page(uint8_t addr, uint8_t page) { | 87 | void is31fl3737_select_page(uint8_t index, uint8_t page) { |
| 75 | is31fl3737_write_register(addr, IS31FL3737_REG_COMMAND_WRITE_LOCK, IS31FL3737_COMMAND_WRITE_LOCK_MAGIC); | 88 | is31fl3737_write_register(index, IS31FL3737_REG_COMMAND_WRITE_LOCK, IS31FL3737_COMMAND_WRITE_LOCK_MAGIC); |
| 76 | is31fl3737_write_register(addr, IS31FL3737_REG_COMMAND, page); | 89 | is31fl3737_write_register(index, IS31FL3737_REG_COMMAND, page); |
| 77 | } | 90 | } |
| 78 | 91 | ||
| 79 | void is31fl3737_write_pwm_buffer(uint8_t addr, uint8_t index) { | 92 | void is31fl3737_write_pwm_buffer(uint8_t index) { |
| 80 | // Assumes page 1 is already selected. | 93 | // Assumes page 1 is already selected. |
| 81 | // Transmit PWM registers in 12 transfers of 16 bytes. | 94 | // Transmit PWM registers in 12 transfers of 16 bytes. |
| 82 | 95 | ||
| @@ -84,10 +97,10 @@ void is31fl3737_write_pwm_buffer(uint8_t addr, uint8_t index) { | |||
| 84 | for (uint8_t i = 0; i < IS31FL3737_PWM_REGISTER_COUNT; i += 16) { | 97 | for (uint8_t i = 0; i < IS31FL3737_PWM_REGISTER_COUNT; i += 16) { |
| 85 | #if IS31FL3737_I2C_PERSISTENCE > 0 | 98 | #if IS31FL3737_I2C_PERSISTENCE > 0 |
| 86 | for (uint8_t j = 0; j < IS31FL3737_I2C_PERSISTENCE; j++) { | 99 | for (uint8_t j = 0; j < IS31FL3737_I2C_PERSISTENCE; j++) { |
| 87 | if (i2c_write_register(addr << 1, i, g_pwm_buffer[index] + i, 16, IS31FL3737_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; | 100 | if (i2c_write_register(i2c_addresses[index] << 1, i, g_pwm_buffer[index] + i, 16, IS31FL3737_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; |
| 88 | } | 101 | } |
| 89 | #else | 102 | #else |
| 90 | i2c_write_register(addr << 1, i, g_pwm_buffer[index] + i, 16, IS31FL3737_I2C_TIMEOUT); | 103 | i2c_write_register(i2c_addresses[index] << 1, i, g_pwm_buffer[index] + i, 16, IS31FL3737_I2C_TIMEOUT); |
| 91 | #endif | 104 | #endif |
| 92 | } | 105 | } |
| 93 | } | 106 | } |
| @@ -95,64 +108,50 @@ void is31fl3737_write_pwm_buffer(uint8_t addr, uint8_t index) { | |||
| 95 | void is31fl3737_init_drivers(void) { | 108 | void is31fl3737_init_drivers(void) { |
| 96 | i2c_init(); | 109 | i2c_init(); |
| 97 | 110 | ||
| 98 | is31fl3737_init(IS31FL3737_I2C_ADDRESS_1); | 111 | for (uint8_t i = 0; i < IS31FL3737_DRIVER_COUNT; i++) { |
| 99 | #if defined(IS31FL3737_I2C_ADDRESS_2) | 112 | is31fl3737_init(i); |
| 100 | is31fl3737_init(IS31FL3737_I2C_ADDRESS_2); | 113 | } |
| 101 | # if defined(IS31FL3737_I2C_ADDRESS_3) | ||
| 102 | is31fl3737_init(IS31FL3737_I2C_ADDRESS_3); | ||
| 103 | # if defined(IS31FL3737_I2C_ADDRESS_4) | ||
| 104 | is31fl3737_init(IS31FL3737_I2C_ADDRESS_4); | ||
| 105 | # endif | ||
| 106 | # endif | ||
| 107 | #endif | ||
| 108 | 114 | ||
| 109 | for (int i = 0; i < IS31FL3737_LED_COUNT; i++) { | 115 | for (int i = 0; i < IS31FL3737_LED_COUNT; i++) { |
| 110 | is31fl3737_set_led_control_register(i, true); | 116 | is31fl3737_set_led_control_register(i, true); |
| 111 | } | 117 | } |
| 112 | 118 | ||
| 113 | is31fl3737_update_led_control_registers(IS31FL3737_I2C_ADDRESS_1, 0); | 119 | for (uint8_t i = 0; i < IS31FL3737_DRIVER_COUNT; i++) { |
| 114 | #if defined(IS31FL3737_I2C_ADDRESS_2) | 120 | is31fl3737_update_led_control_registers(i); |
| 115 | is31fl3737_update_led_control_registers(IS31FL3737_I2C_ADDRESS_2, 1); | 121 | } |
| 116 | # if defined(IS31FL3737_I2C_ADDRESS_3) | ||
| 117 | is31fl3737_update_led_control_registers(IS31FL3737_I2C_ADDRESS_3, 2); | ||
| 118 | # if defined(IS31FL3737_I2C_ADDRESS_4) | ||
| 119 | is31fl3737_update_led_control_registers(IS31FL3737_I2C_ADDRESS_4, 3); | ||
| 120 | # endif | ||
| 121 | # endif | ||
| 122 | #endif | ||
| 123 | } | 122 | } |
| 124 | 123 | ||
| 125 | void is31fl3737_init(uint8_t addr) { | 124 | void is31fl3737_init(uint8_t index) { |
| 126 | // In order to avoid the LEDs being driven with garbage data | 125 | // In order to avoid the LEDs being driven with garbage data |
| 127 | // in the LED driver's PWM registers, shutdown is enabled last. | 126 | // in the LED driver's PWM registers, shutdown is enabled last. |
| 128 | // Set up the mode and other settings, clear the PWM registers, | 127 | // Set up the mode and other settings, clear the PWM registers, |
| 129 | // then disable software shutdown. | 128 | // then disable software shutdown. |
| 130 | 129 | ||
| 131 | is31fl3737_select_page(addr, IS31FL3737_COMMAND_LED_CONTROL); | 130 | is31fl3737_select_page(index, IS31FL3737_COMMAND_LED_CONTROL); |
| 132 | 131 | ||
| 133 | // Turn off all LEDs. | 132 | // Turn off all LEDs. |
| 134 | for (uint8_t i = 0; i < IS31FL3737_LED_CONTROL_REGISTER_COUNT; i++) { | 133 | for (uint8_t i = 0; i < IS31FL3737_LED_CONTROL_REGISTER_COUNT; i++) { |
| 135 | is31fl3737_write_register(addr, i, 0x00); | 134 | is31fl3737_write_register(index, i, 0x00); |
| 136 | } | 135 | } |
| 137 | 136 | ||
| 138 | is31fl3737_select_page(addr, IS31FL3737_COMMAND_PWM); | 137 | is31fl3737_select_page(index, IS31FL3737_COMMAND_PWM); |
| 139 | 138 | ||
| 140 | // Set PWM on all LEDs to 0 | 139 | // Set PWM on all LEDs to 0 |
| 141 | // No need to setup Breath registers to PWM as that is the default. | 140 | // No need to setup Breath registers to PWM as that is the default. |
| 142 | for (uint8_t i = 0; i < IS31FL3737_PWM_REGISTER_COUNT; i++) { | 141 | for (uint8_t i = 0; i < IS31FL3737_PWM_REGISTER_COUNT; i++) { |
| 143 | is31fl3737_write_register(addr, i, 0x00); | 142 | is31fl3737_write_register(index, i, 0x00); |
| 144 | } | 143 | } |
| 145 | 144 | ||
| 146 | is31fl3737_select_page(addr, IS31FL3737_COMMAND_FUNCTION); | 145 | is31fl3737_select_page(index, IS31FL3737_COMMAND_FUNCTION); |
| 147 | 146 | ||
| 148 | // Set de-ghost pull-up resistors (SWx) | 147 | // Set de-ghost pull-up resistors (SWx) |
| 149 | is31fl3737_write_register(addr, IS31FL3737_FUNCTION_REG_SW_PULLUP, IS31FL3737_SW_PULLUP); | 148 | is31fl3737_write_register(index, IS31FL3737_FUNCTION_REG_SW_PULLUP, IS31FL3737_SW_PULLUP); |
| 150 | // Set de-ghost pull-down resistors (CSx) | 149 | // Set de-ghost pull-down resistors (CSx) |
| 151 | is31fl3737_write_register(addr, IS31FL3737_FUNCTION_REG_CS_PULLDOWN, IS31FL3737_CS_PULLDOWN); | 150 | is31fl3737_write_register(index, IS31FL3737_FUNCTION_REG_CS_PULLDOWN, IS31FL3737_CS_PULLDOWN); |
| 152 | // Set global current to maximum. | 151 | // Set global current to maximum. |
| 153 | is31fl3737_write_register(addr, IS31FL3737_FUNCTION_REG_GLOBAL_CURRENT, IS31FL3737_GLOBAL_CURRENT); | 152 | is31fl3737_write_register(index, IS31FL3737_FUNCTION_REG_GLOBAL_CURRENT, IS31FL3737_GLOBAL_CURRENT); |
| 154 | // Disable software shutdown. | 153 | // Disable software shutdown. |
| 155 | is31fl3737_write_register(addr, IS31FL3737_FUNCTION_REG_CONFIGURATION, ((IS31FL3737_PWM_FREQUENCY & 0b111) << 3) | 0x01); | 154 | is31fl3737_write_register(index, IS31FL3737_FUNCTION_REG_CONFIGURATION, ((IS31FL3737_PWM_FREQUENCY & 0b111) << 3) | 0x01); |
| 156 | 155 | ||
| 157 | // Wait 10ms to ensure the device has woken up. | 156 | // Wait 10ms to ensure the device has woken up. |
| 158 | wait_ms(10); | 157 | wait_ms(10); |
| @@ -195,22 +194,22 @@ void is31fl3737_set_led_control_register(uint8_t index, bool value) { | |||
| 195 | g_led_control_registers_update_required[led.driver] = true; | 194 | g_led_control_registers_update_required[led.driver] = true; |
| 196 | } | 195 | } |
| 197 | 196 | ||
| 198 | void is31fl3737_update_pwm_buffers(uint8_t addr, uint8_t index) { | 197 | void is31fl3737_update_pwm_buffers(uint8_t index) { |
| 199 | if (g_pwm_buffer_update_required[index]) { | 198 | if (g_pwm_buffer_update_required[index]) { |
| 200 | is31fl3737_select_page(addr, IS31FL3737_COMMAND_PWM); | 199 | is31fl3737_select_page(index, IS31FL3737_COMMAND_PWM); |
| 201 | 200 | ||
| 202 | is31fl3737_write_pwm_buffer(addr, index); | 201 | is31fl3737_write_pwm_buffer(index); |
| 203 | 202 | ||
| 204 | g_pwm_buffer_update_required[index] = false; | 203 | g_pwm_buffer_update_required[index] = false; |
| 205 | } | 204 | } |
| 206 | } | 205 | } |
| 207 | 206 | ||
| 208 | void is31fl3737_update_led_control_registers(uint8_t addr, uint8_t index) { | 207 | void is31fl3737_update_led_control_registers(uint8_t index) { |
| 209 | if (g_led_control_registers_update_required[index]) { | 208 | if (g_led_control_registers_update_required[index]) { |
| 210 | is31fl3737_select_page(addr, IS31FL3737_COMMAND_LED_CONTROL); | 209 | is31fl3737_select_page(index, IS31FL3737_COMMAND_LED_CONTROL); |
| 211 | 210 | ||
| 212 | for (uint8_t i = 0; i < IS31FL3737_LED_CONTROL_REGISTER_COUNT; i++) { | 211 | for (uint8_t i = 0; i < IS31FL3737_LED_CONTROL_REGISTER_COUNT; i++) { |
| 213 | is31fl3737_write_register(addr, i, g_led_control_registers[index][i]); | 212 | is31fl3737_write_register(index, i, g_led_control_registers[index][i]); |
| 214 | } | 213 | } |
| 215 | 214 | ||
| 216 | g_led_control_registers_update_required[index] = false; | 215 | g_led_control_registers_update_required[index] = false; |
| @@ -218,14 +217,7 @@ void is31fl3737_update_led_control_registers(uint8_t addr, uint8_t index) { | |||
| 218 | } | 217 | } |
| 219 | 218 | ||
| 220 | void is31fl3737_flush(void) { | 219 | void is31fl3737_flush(void) { |
| 221 | is31fl3737_update_pwm_buffers(IS31FL3737_I2C_ADDRESS_1, 0); | 220 | for (uint8_t i = 0; i < IS31FL3737_DRIVER_COUNT; i++) { |
| 222 | #if defined(IS31FL3737_I2C_ADDRESS_2) | 221 | is31fl3737_update_pwm_buffers(i); |
| 223 | is31fl3737_update_pwm_buffers(IS31FL3737_I2C_ADDRESS_2, 1); | 222 | } |
| 224 | # if defined(IS31FL3737_I2C_ADDRESS_3) | ||
| 225 | is31fl3737_update_pwm_buffers(IS31FL3737_I2C_ADDRESS_3, 2); | ||
| 226 | # if defined(IS31FL3737_I2C_ADDRESS_4) | ||
| 227 | is31fl3737_update_pwm_buffers(IS31FL3737_I2C_ADDRESS_4, 3); | ||
| 228 | # endif | ||
| 229 | # endif | ||
| 230 | #endif | ||
| 231 | } | 223 | } |
diff --git a/drivers/led/issi/is31fl3737-mono.h b/drivers/led/issi/is31fl3737-mono.h index 6d081bfa00..8c0b5ee30b 100644 --- a/drivers/led/issi/is31fl3737-mono.h +++ b/drivers/led/issi/is31fl3737-mono.h | |||
| @@ -100,9 +100,9 @@ typedef struct is31fl3737_led_t { | |||
| 100 | extern const is31fl3737_led_t PROGMEM g_is31fl3737_leds[IS31FL3737_LED_COUNT]; | 100 | extern const is31fl3737_led_t PROGMEM g_is31fl3737_leds[IS31FL3737_LED_COUNT]; |
| 101 | 101 | ||
| 102 | void is31fl3737_init_drivers(void); | 102 | void is31fl3737_init_drivers(void); |
| 103 | void is31fl3737_init(uint8_t addr); | 103 | void is31fl3737_init(uint8_t index); |
| 104 | void is31fl3737_write_register(uint8_t addr, uint8_t reg, uint8_t data); | 104 | void is31fl3737_write_register(uint8_t index, uint8_t reg, uint8_t data); |
| 105 | void is31fl3737_select_page(uint8_t addr, uint8_t page); | 105 | void is31fl3737_select_page(uint8_t index, uint8_t page); |
| 106 | 106 | ||
| 107 | void is31fl3737_set_value(int index, uint8_t value); | 107 | void is31fl3737_set_value(int index, uint8_t value); |
| 108 | void is31fl3737_set_value_all(uint8_t value); | 108 | void is31fl3737_set_value_all(uint8_t value); |
| @@ -113,8 +113,8 @@ void is31fl3737_set_led_control_register(uint8_t index, bool value); | |||
| 113 | // (eg. from a timer interrupt). | 113 | // (eg. from a timer interrupt). |
| 114 | // Call this while idle (in between matrix scans). | 114 | // Call this while idle (in between matrix scans). |
| 115 | // If the buffer is dirty, it will update the driver with the buffer. | 115 | // If the buffer is dirty, it will update the driver with the buffer. |
| 116 | void is31fl3737_update_pwm_buffers(uint8_t addr, uint8_t index); | 116 | void is31fl3737_update_pwm_buffers(uint8_t index); |
| 117 | void is31fl3737_update_led_control_registers(uint8_t addr, uint8_t index); | 117 | void is31fl3737_update_led_control_registers(uint8_t index); |
| 118 | 118 | ||
| 119 | void is31fl3737_flush(void); | 119 | void is31fl3737_flush(void); |
| 120 | 120 | ||
diff --git a/drivers/led/issi/is31fl3737.c b/drivers/led/issi/is31fl3737.c index e17d73c36f..20f068038a 100644 --- a/drivers/led/issi/is31fl3737.c +++ b/drivers/led/issi/is31fl3737.c | |||
| @@ -48,6 +48,19 @@ | |||
| 48 | # define IS31FL3737_GLOBAL_CURRENT 0xFF | 48 | # define IS31FL3737_GLOBAL_CURRENT 0xFF |
| 49 | #endif | 49 | #endif |
| 50 | 50 | ||
| 51 | const uint8_t i2c_addresses[IS31FL3737_DRIVER_COUNT] = { | ||
| 52 | IS31FL3737_I2C_ADDRESS_1, | ||
| 53 | #ifdef IS31FL3737_I2C_ADDRESS_2 | ||
| 54 | IS31FL3737_I2C_ADDRESS_2, | ||
| 55 | # ifdef IS31FL3737_I2C_ADDRESS_3 | ||
| 56 | IS31FL3737_I2C_ADDRESS_3, | ||
| 57 | # ifdef IS31FL3737_I2C_ADDRESS_4 | ||
| 58 | IS31FL3737_I2C_ADDRESS_4, | ||
| 59 | # endif | ||
| 60 | # endif | ||
| 61 | #endif | ||
| 62 | }; | ||
| 63 | |||
| 51 | // These buffers match the IS31FL3737 PWM registers. | 64 | // These buffers match the IS31FL3737 PWM registers. |
| 52 | // The control buffers match the page 0 LED On/Off registers. | 65 | // The control buffers match the page 0 LED On/Off registers. |
| 53 | // Storing them like this is optimal for I2C transfers to the registers. | 66 | // Storing them like this is optimal for I2C transfers to the registers. |
| @@ -61,22 +74,22 @@ bool g_pwm_buffer_update_required[IS31FL3737_DRIVER_COUNT] = {false}; | |||
| 61 | uint8_t g_led_control_registers[IS31FL3737_DRIVER_COUNT][IS31FL3737_LED_CONTROL_REGISTER_COUNT] = {0}; | 74 | uint8_t g_led_control_registers[IS31FL3737_DRIVER_COUNT][IS31FL3737_LED_CONTROL_REGISTER_COUNT] = {0}; |
| 62 | bool g_led_control_registers_update_required[IS31FL3737_DRIVER_COUNT] = {false}; | 75 | bool g_led_control_registers_update_required[IS31FL3737_DRIVER_COUNT] = {false}; |
| 63 | 76 | ||
| 64 | void is31fl3737_write_register(uint8_t addr, uint8_t reg, uint8_t data) { | 77 | void is31fl3737_write_register(uint8_t index, uint8_t reg, uint8_t data) { |
| 65 | #if IS31FL3737_I2C_PERSISTENCE > 0 | 78 | #if IS31FL3737_I2C_PERSISTENCE > 0 |
| 66 | for (uint8_t i = 0; i < IS31FL3737_I2C_PERSISTENCE; i++) { | 79 | for (uint8_t i = 0; i < IS31FL3737_I2C_PERSISTENCE; i++) { |
| 67 | if (i2c_write_register(addr << 1, reg, &data, 1, IS31FL3737_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; | 80 | if (i2c_write_register(i2c_addresses[index] << 1, reg, &data, 1, IS31FL3737_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; |
| 68 | } | 81 | } |
| 69 | #else | 82 | #else |
| 70 | i2c_write_register(addr << 1, reg, &data, 1, IS31FL3737_I2C_TIMEOUT); | 83 | i2c_write_register(i2c_addresses[index] << 1, reg, &data, 1, IS31FL3737_I2C_TIMEOUT); |
| 71 | #endif | 84 | #endif |
| 72 | } | 85 | } |
| 73 | 86 | ||
| 74 | void is31fl3737_select_page(uint8_t addr, uint8_t page) { | 87 | void is31fl3737_select_page(uint8_t index, uint8_t page) { |
| 75 | is31fl3737_write_register(addr, IS31FL3737_REG_COMMAND_WRITE_LOCK, IS31FL3737_COMMAND_WRITE_LOCK_MAGIC); | 88 | is31fl3737_write_register(index, IS31FL3737_REG_COMMAND_WRITE_LOCK, IS31FL3737_COMMAND_WRITE_LOCK_MAGIC); |
| 76 | is31fl3737_write_register(addr, IS31FL3737_REG_COMMAND, page); | 89 | is31fl3737_write_register(index, IS31FL3737_REG_COMMAND, page); |
| 77 | } | 90 | } |
| 78 | 91 | ||
| 79 | void is31fl3737_write_pwm_buffer(uint8_t addr, uint8_t index) { | 92 | void is31fl3737_write_pwm_buffer(uint8_t index) { |
| 80 | // Assumes page 1 is already selected. | 93 | // Assumes page 1 is already selected. |
| 81 | // Transmit PWM registers in 12 transfers of 16 bytes. | 94 | // Transmit PWM registers in 12 transfers of 16 bytes. |
| 82 | 95 | ||
| @@ -84,10 +97,10 @@ void is31fl3737_write_pwm_buffer(uint8_t addr, uint8_t index) { | |||
| 84 | for (uint8_t i = 0; i < IS31FL3737_PWM_REGISTER_COUNT; i += 16) { | 97 | for (uint8_t i = 0; i < IS31FL3737_PWM_REGISTER_COUNT; i += 16) { |
| 85 | #if IS31FL3737_I2C_PERSISTENCE > 0 | 98 | #if IS31FL3737_I2C_PERSISTENCE > 0 |
| 86 | for (uint8_t j = 0; j < IS31FL3737_I2C_PERSISTENCE; j++) { | 99 | for (uint8_t j = 0; j < IS31FL3737_I2C_PERSISTENCE; j++) { |
| 87 | if (i2c_write_register(addr << 1, i, g_pwm_buffer[index] + i, 16, IS31FL3737_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; | 100 | if (i2c_write_register(i2c_addresses[index] << 1, i, g_pwm_buffer[index] + i, 16, IS31FL3737_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; |
| 88 | } | 101 | } |
| 89 | #else | 102 | #else |
| 90 | i2c_write_register(addr << 1, i, g_pwm_buffer[index] + i, 16, IS31FL3737_I2C_TIMEOUT); | 103 | i2c_write_register(i2c_addresses[index] << 1, i, g_pwm_buffer[index] + i, 16, IS31FL3737_I2C_TIMEOUT); |
| 91 | #endif | 104 | #endif |
| 92 | } | 105 | } |
| 93 | } | 106 | } |
| @@ -95,64 +108,50 @@ void is31fl3737_write_pwm_buffer(uint8_t addr, uint8_t index) { | |||
| 95 | void is31fl3737_init_drivers(void) { | 108 | void is31fl3737_init_drivers(void) { |
| 96 | i2c_init(); | 109 | i2c_init(); |
| 97 | 110 | ||
| 98 | is31fl3737_init(IS31FL3737_I2C_ADDRESS_1); | 111 | for (uint8_t i = 0; i < IS31FL3737_DRIVER_COUNT; i++) { |
| 99 | #if defined(IS31FL3737_I2C_ADDRESS_2) | 112 | is31fl3737_init(i); |
| 100 | is31fl3737_init(IS31FL3737_I2C_ADDRESS_2); | 113 | } |
| 101 | # if defined(IS31FL3737_I2C_ADDRESS_3) | ||
| 102 | is31fl3737_init(IS31FL3737_I2C_ADDRESS_3); | ||
| 103 | # if defined(IS31FL3737_I2C_ADDRESS_4) | ||
| 104 | is31fl3737_init(IS31FL3737_I2C_ADDRESS_4); | ||
| 105 | # endif | ||
| 106 | # endif | ||
| 107 | #endif | ||
| 108 | 114 | ||
| 109 | for (int i = 0; i < IS31FL3737_LED_COUNT; i++) { | 115 | for (int i = 0; i < IS31FL3737_LED_COUNT; i++) { |
| 110 | is31fl3737_set_led_control_register(i, true, true, true); | 116 | is31fl3737_set_led_control_register(i, true, true, true); |
| 111 | } | 117 | } |
| 112 | 118 | ||
| 113 | is31fl3737_update_led_control_registers(IS31FL3737_I2C_ADDRESS_1, 0); | 119 | for (uint8_t i = 0; i < IS31FL3737_DRIVER_COUNT; i++) { |
| 114 | #if defined(IS31FL3737_I2C_ADDRESS_2) | 120 | is31fl3737_update_led_control_registers(i); |
| 115 | is31fl3737_update_led_control_registers(IS31FL3737_I2C_ADDRESS_2, 1); | 121 | } |
| 116 | # if defined(IS31FL3737_I2C_ADDRESS_3) | ||
| 117 | is31fl3737_update_led_control_registers(IS31FL3737_I2C_ADDRESS_3, 2); | ||
| 118 | # if defined(IS31FL3737_I2C_ADDRESS_4) | ||
| 119 | is31fl3737_update_led_control_registers(IS31FL3737_I2C_ADDRESS_4, 3); | ||
| 120 | # endif | ||
| 121 | # endif | ||
| 122 | #endif | ||
| 123 | } | 122 | } |
| 124 | 123 | ||
| 125 | void is31fl3737_init(uint8_t addr) { | 124 | void is31fl3737_init(uint8_t index) { |
| 126 | // In order to avoid the LEDs being driven with garbage data | 125 | // In order to avoid the LEDs being driven with garbage data |
| 127 | // in the LED driver's PWM registers, shutdown is enabled last. | 126 | // in the LED driver's PWM registers, shutdown is enabled last. |
| 128 | // Set up the mode and other settings, clear the PWM registers, | 127 | // Set up the mode and other settings, clear the PWM registers, |
| 129 | // then disable software shutdown. | 128 | // then disable software shutdown. |
| 130 | 129 | ||
| 131 | is31fl3737_select_page(addr, IS31FL3737_COMMAND_LED_CONTROL); | 130 | is31fl3737_select_page(index, IS31FL3737_COMMAND_LED_CONTROL); |
| 132 | 131 | ||
| 133 | // Turn off all LEDs. | 132 | // Turn off all LEDs. |
| 134 | for (uint8_t i = 0; i < IS31FL3737_LED_CONTROL_REGISTER_COUNT; i++) { | 133 | for (uint8_t i = 0; i < IS31FL3737_LED_CONTROL_REGISTER_COUNT; i++) { |
| 135 | is31fl3737_write_register(addr, i, 0x00); | 134 | is31fl3737_write_register(index, i, 0x00); |
| 136 | } | 135 | } |
| 137 | 136 | ||
| 138 | is31fl3737_select_page(addr, IS31FL3737_COMMAND_PWM); | 137 | is31fl3737_select_page(index, IS31FL3737_COMMAND_PWM); |
| 139 | 138 | ||
| 140 | // Set PWM on all LEDs to 0 | 139 | // Set PWM on all LEDs to 0 |
| 141 | // No need to setup Breath registers to PWM as that is the default. | 140 | // No need to setup Breath registers to PWM as that is the default. |
| 142 | for (uint8_t i = 0; i < IS31FL3737_PWM_REGISTER_COUNT; i++) { | 141 | for (uint8_t i = 0; i < IS31FL3737_PWM_REGISTER_COUNT; i++) { |
| 143 | is31fl3737_write_register(addr, i, 0x00); | 142 | is31fl3737_write_register(index, i, 0x00); |
| 144 | } | 143 | } |
| 145 | 144 | ||
| 146 | is31fl3737_select_page(addr, IS31FL3737_COMMAND_FUNCTION); | 145 | is31fl3737_select_page(index, IS31FL3737_COMMAND_FUNCTION); |
| 147 | 146 | ||
| 148 | // Set de-ghost pull-up resistors (SWx) | 147 | // Set de-ghost pull-up resistors (SWx) |
| 149 | is31fl3737_write_register(addr, IS31FL3737_FUNCTION_REG_SW_PULLUP, IS31FL3737_SW_PULLUP); | 148 | is31fl3737_write_register(index, IS31FL3737_FUNCTION_REG_SW_PULLUP, IS31FL3737_SW_PULLUP); |
| 150 | // Set de-ghost pull-down resistors (CSx) | 149 | // Set de-ghost pull-down resistors (CSx) |
| 151 | is31fl3737_write_register(addr, IS31FL3737_FUNCTION_REG_CS_PULLDOWN, IS31FL3737_CS_PULLDOWN); | 150 | is31fl3737_write_register(index, IS31FL3737_FUNCTION_REG_CS_PULLDOWN, IS31FL3737_CS_PULLDOWN); |
| 152 | // Set global current to maximum. | 151 | // Set global current to maximum. |
| 153 | is31fl3737_write_register(addr, IS31FL3737_FUNCTION_REG_GLOBAL_CURRENT, IS31FL3737_GLOBAL_CURRENT); | 152 | is31fl3737_write_register(index, IS31FL3737_FUNCTION_REG_GLOBAL_CURRENT, IS31FL3737_GLOBAL_CURRENT); |
| 154 | // Disable software shutdown. | 153 | // Disable software shutdown. |
| 155 | is31fl3737_write_register(addr, IS31FL3737_FUNCTION_REG_CONFIGURATION, ((IS31FL3737_PWM_FREQUENCY & 0b111) << 3) | 0x01); | 154 | is31fl3737_write_register(index, IS31FL3737_FUNCTION_REG_CONFIGURATION, ((IS31FL3737_PWM_FREQUENCY & 0b111) << 3) | 0x01); |
| 156 | 155 | ||
| 157 | // Wait 10ms to ensure the device has woken up. | 156 | // Wait 10ms to ensure the device has woken up. |
| 158 | wait_ms(10); | 157 | wait_ms(10); |
| @@ -211,22 +210,22 @@ void is31fl3737_set_led_control_register(uint8_t index, bool red, bool green, bo | |||
| 211 | g_led_control_registers_update_required[led.driver] = true; | 210 | g_led_control_registers_update_required[led.driver] = true; |
| 212 | } | 211 | } |
| 213 | 212 | ||
| 214 | void is31fl3737_update_pwm_buffers(uint8_t addr, uint8_t index) { | 213 | void is31fl3737_update_pwm_buffers(uint8_t index) { |
| 215 | if (g_pwm_buffer_update_required[index]) { | 214 | if (g_pwm_buffer_update_required[index]) { |
| 216 | is31fl3737_select_page(addr, IS31FL3737_COMMAND_PWM); | 215 | is31fl3737_select_page(index, IS31FL3737_COMMAND_PWM); |
| 217 | 216 | ||
| 218 | is31fl3737_write_pwm_buffer(addr, index); | 217 | is31fl3737_write_pwm_buffer(index); |
| 219 | 218 | ||
| 220 | g_pwm_buffer_update_required[index] = false; | 219 | g_pwm_buffer_update_required[index] = false; |
| 221 | } | 220 | } |
| 222 | } | 221 | } |
| 223 | 222 | ||
| 224 | void is31fl3737_update_led_control_registers(uint8_t addr, uint8_t index) { | 223 | void is31fl3737_update_led_control_registers(uint8_t index) { |
| 225 | if (g_led_control_registers_update_required[index]) { | 224 | if (g_led_control_registers_update_required[index]) { |
| 226 | is31fl3737_select_page(addr, IS31FL3737_COMMAND_LED_CONTROL); | 225 | is31fl3737_select_page(index, IS31FL3737_COMMAND_LED_CONTROL); |
| 227 | 226 | ||
| 228 | for (uint8_t i = 0; i < IS31FL3737_LED_CONTROL_REGISTER_COUNT; i++) { | 227 | for (uint8_t i = 0; i < IS31FL3737_LED_CONTROL_REGISTER_COUNT; i++) { |
| 229 | is31fl3737_write_register(addr, i, g_led_control_registers[index][i]); | 228 | is31fl3737_write_register(index, i, g_led_control_registers[index][i]); |
| 230 | } | 229 | } |
| 231 | 230 | ||
| 232 | g_led_control_registers_update_required[index] = false; | 231 | g_led_control_registers_update_required[index] = false; |
| @@ -234,14 +233,7 @@ void is31fl3737_update_led_control_registers(uint8_t addr, uint8_t index) { | |||
| 234 | } | 233 | } |
| 235 | 234 | ||
| 236 | void is31fl3737_flush(void) { | 235 | void is31fl3737_flush(void) { |
| 237 | is31fl3737_update_pwm_buffers(IS31FL3737_I2C_ADDRESS_1, 0); | 236 | for (uint8_t i = 0; i < IS31FL3737_DRIVER_COUNT; i++) { |
| 238 | #if defined(IS31FL3737_I2C_ADDRESS_2) | 237 | is31fl3737_update_pwm_buffers(i); |
| 239 | is31fl3737_update_pwm_buffers(IS31FL3737_I2C_ADDRESS_2, 1); | 238 | } |
| 240 | # if defined(IS31FL3737_I2C_ADDRESS_3) | ||
| 241 | is31fl3737_update_pwm_buffers(IS31FL3737_I2C_ADDRESS_3, 2); | ||
| 242 | # if defined(IS31FL3737_I2C_ADDRESS_4) | ||
| 243 | is31fl3737_update_pwm_buffers(IS31FL3737_I2C_ADDRESS_4, 3); | ||
| 244 | # endif | ||
| 245 | # endif | ||
| 246 | #endif | ||
| 247 | } | 239 | } |
diff --git a/drivers/led/issi/is31fl3737.h b/drivers/led/issi/is31fl3737.h index 7f0d86df82..d8f42bec29 100644 --- a/drivers/led/issi/is31fl3737.h +++ b/drivers/led/issi/is31fl3737.h | |||
| @@ -117,9 +117,9 @@ typedef struct is31fl3737_led_t { | |||
| 117 | extern const is31fl3737_led_t PROGMEM g_is31fl3737_leds[IS31FL3737_LED_COUNT]; | 117 | extern const is31fl3737_led_t PROGMEM g_is31fl3737_leds[IS31FL3737_LED_COUNT]; |
| 118 | 118 | ||
| 119 | void is31fl3737_init_drivers(void); | 119 | void is31fl3737_init_drivers(void); |
| 120 | void is31fl3737_init(uint8_t addr); | 120 | void is31fl3737_init(uint8_t index); |
| 121 | void is31fl3737_write_register(uint8_t addr, uint8_t reg, uint8_t data); | 121 | void is31fl3737_write_register(uint8_t index, uint8_t reg, uint8_t data); |
| 122 | void is31fl3737_select_page(uint8_t addr, uint8_t page); | 122 | void is31fl3737_select_page(uint8_t index, uint8_t page); |
| 123 | 123 | ||
| 124 | void is31fl3737_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); | 124 | void is31fl3737_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); |
| 125 | void is31fl3737_set_color_all(uint8_t red, uint8_t green, uint8_t blue); | 125 | void is31fl3737_set_color_all(uint8_t red, uint8_t green, uint8_t blue); |
| @@ -130,8 +130,8 @@ void is31fl3737_set_led_control_register(uint8_t index, bool red, bool green, bo | |||
| 130 | // (eg. from a timer interrupt). | 130 | // (eg. from a timer interrupt). |
| 131 | // Call this while idle (in between matrix scans). | 131 | // Call this while idle (in between matrix scans). |
| 132 | // If the buffer is dirty, it will update the driver with the buffer. | 132 | // If the buffer is dirty, it will update the driver with the buffer. |
| 133 | void is31fl3737_update_pwm_buffers(uint8_t addr, uint8_t index); | 133 | void is31fl3737_update_pwm_buffers(uint8_t index); |
| 134 | void is31fl3737_update_led_control_registers(uint8_t addr, uint8_t index); | 134 | void is31fl3737_update_led_control_registers(uint8_t index); |
| 135 | 135 | ||
| 136 | void is31fl3737_flush(void); | 136 | void is31fl3737_flush(void); |
| 137 | 137 | ||
diff --git a/drivers/led/issi/is31fl3741-mono.c b/drivers/led/issi/is31fl3741-mono.c index 4f388f56b0..dbe99f2f88 100644 --- a/drivers/led/issi/is31fl3741-mono.c +++ b/drivers/led/issi/is31fl3741-mono.c | |||
| @@ -52,6 +52,19 @@ | |||
| 52 | # define IS31FL3741_GLOBAL_CURRENT 0xFF | 52 | # define IS31FL3741_GLOBAL_CURRENT 0xFF |
| 53 | #endif | 53 | #endif |
| 54 | 54 | ||
| 55 | const uint8_t i2c_addresses[IS31FL3741_DRIVER_COUNT] = { | ||
| 56 | IS31FL3741_I2C_ADDRESS_1, | ||
| 57 | #ifdef IS31FL3741_I2C_ADDRESS_2 | ||
| 58 | IS31FL3741_I2C_ADDRESS_2, | ||
| 59 | # ifdef IS31FL3741_I2C_ADDRESS_3 | ||
| 60 | IS31FL3741_I2C_ADDRESS_3, | ||
| 61 | # ifdef IS31FL3741_I2C_ADDRESS_4 | ||
| 62 | IS31FL3741_I2C_ADDRESS_4, | ||
| 63 | # endif | ||
| 64 | # endif | ||
| 65 | #endif | ||
| 66 | }; | ||
| 67 | |||
| 55 | // These buffers match the IS31FL3741 and IS31FL3741A PWM registers. | 68 | // These buffers match the IS31FL3741 and IS31FL3741A PWM registers. |
| 56 | // The scaling buffers match the page 2 and 3 LED On/Off registers. | 69 | // The scaling buffers match the page 2 and 3 LED On/Off registers. |
| 57 | // Storing them like this is optimal for I2C transfers to the registers. | 70 | // Storing them like this is optimal for I2C transfers to the registers. |
| @@ -64,98 +77,84 @@ bool g_scaling_registers_update_required[IS31FL3741_DRIVER_COUNT] = {false}; | |||
| 64 | 77 | ||
| 65 | uint8_t g_scaling_registers[IS31FL3741_DRIVER_COUNT][IS31FL3741_SCALING_REGISTER_COUNT]; | 78 | uint8_t g_scaling_registers[IS31FL3741_DRIVER_COUNT][IS31FL3741_SCALING_REGISTER_COUNT]; |
| 66 | 79 | ||
| 67 | void is31fl3741_write_register(uint8_t addr, uint8_t reg, uint8_t data) { | 80 | void is31fl3741_write_register(uint8_t index, uint8_t reg, uint8_t data) { |
| 68 | #if IS31FL3741_I2C_PERSISTENCE > 0 | 81 | #if IS31FL3741_I2C_PERSISTENCE > 0 |
| 69 | for (uint8_t i = 0; i < IS31FL3741_I2C_PERSISTENCE; i++) { | 82 | for (uint8_t i = 0; i < IS31FL3741_I2C_PERSISTENCE; i++) { |
| 70 | if (i2c_write_register(addr << 1, reg, &data, 1, IS31FL3741_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; | 83 | if (i2c_write_register(i2c_addresses[index] << 1, reg, &data, 1, IS31FL3741_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; |
| 71 | } | 84 | } |
| 72 | #else | 85 | #else |
| 73 | i2c_write_register(addr << 1, reg, &data, 1, IS31FL3741_I2C_TIMEOUT); | 86 | i2c_write_register(i2c_addresses[index] << 1, reg, &data, 1, IS31FL3741_I2C_TIMEOUT); |
| 74 | #endif | 87 | #endif |
| 75 | } | 88 | } |
| 76 | 89 | ||
| 77 | void is31fl3741_select_page(uint8_t addr, uint8_t page) { | 90 | void is31fl3741_select_page(uint8_t index, uint8_t page) { |
| 78 | is31fl3741_write_register(addr, IS31FL3741_REG_COMMAND_WRITE_LOCK, IS31FL3741_COMMAND_WRITE_LOCK_MAGIC); | 91 | is31fl3741_write_register(index, IS31FL3741_REG_COMMAND_WRITE_LOCK, IS31FL3741_COMMAND_WRITE_LOCK_MAGIC); |
| 79 | is31fl3741_write_register(addr, IS31FL3741_REG_COMMAND, page); | 92 | is31fl3741_write_register(index, IS31FL3741_REG_COMMAND, page); |
| 80 | } | 93 | } |
| 81 | 94 | ||
| 82 | void is31fl3741_write_pwm_buffer(uint8_t addr, uint8_t index) { | 95 | void is31fl3741_write_pwm_buffer(uint8_t index) { |
| 83 | // Assume page 0 is already selected | 96 | // Assume page 0 is already selected |
| 84 | 97 | ||
| 85 | for (uint16_t i = 0; i < 342; i += 18) { | 98 | for (uint16_t i = 0; i < 342; i += 18) { |
| 86 | if (i == 180) { | 99 | if (i == 180) { |
| 87 | is31fl3741_select_page(addr, IS31FL3741_COMMAND_PWM_1); | 100 | is31fl3741_select_page(index, IS31FL3741_COMMAND_PWM_1); |
| 88 | } | 101 | } |
| 89 | 102 | ||
| 90 | #if IS31FL3741_I2C_PERSISTENCE > 0 | 103 | #if IS31FL3741_I2C_PERSISTENCE > 0 |
| 91 | for (uint8_t j = 0; j < IS31FL3741_I2C_PERSISTENCE; j++) { | 104 | for (uint8_t j = 0; j < IS31FL3741_I2C_PERSISTENCE; j++) { |
| 92 | if (i2c_write_register(addr << 1, i % 180, g_pwm_buffer[index] + i, 18, IS31FL3741_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; | 105 | if (i2c_write_register(i2c_addresses[index] << 1, i % 180, g_pwm_buffer[index] + i, 18, IS31FL3741_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; |
| 93 | } | 106 | } |
| 94 | #else | 107 | #else |
| 95 | i2c_write_register(addr << 1, i % 180, g_pwm_buffer[index] + i, 18, IS31FL3741_I2C_TIMEOUT); | 108 | i2c_write_register(i2c_addresses[index] << 1, i % 180, g_pwm_buffer[index] + i, 18, IS31FL3741_I2C_TIMEOUT); |
| 96 | #endif | 109 | #endif |
| 97 | } | 110 | } |
| 98 | 111 | ||
| 99 | // transfer the left cause the total number is 351 | 112 | // transfer the left cause the total number is 351 |
| 100 | #if IS31FL3741_I2C_PERSISTENCE > 0 | 113 | #if IS31FL3741_I2C_PERSISTENCE > 0 |
| 101 | for (uint8_t i = 0; i < IS31FL3741_I2C_PERSISTENCE; i++) { | 114 | for (uint8_t i = 0; i < IS31FL3741_I2C_PERSISTENCE; i++) { |
| 102 | if (i2c_write_register(addr << 1, 162, g_pwm_buffer[index] + 342, 9, IS31FL3741_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; | 115 | if (i2c_write_register(i2c_addresses[index] << 1, 162, g_pwm_buffer[index] + 342, 9, IS31FL3741_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; |
| 103 | } | 116 | } |
| 104 | #else | 117 | #else |
| 105 | i2c_write_register(addr << 1, 162, g_pwm_buffer[index] + 342, 9, IS31FL3741_I2C_TIMEOUT); | 118 | i2c_write_register(i2c_addresses[index] << 1, 162, g_pwm_buffer[index] + 342, 9, IS31FL3741_I2C_TIMEOUT); |
| 106 | #endif | 119 | #endif |
| 107 | } | 120 | } |
| 108 | 121 | ||
| 109 | void is31fl3741_init_drivers(void) { | 122 | void is31fl3741_init_drivers(void) { |
| 110 | i2c_init(); | 123 | i2c_init(); |
| 111 | 124 | ||
| 112 | is31fl3741_init(IS31FL3741_I2C_ADDRESS_1); | 125 | for (uint8_t i = 0; i < IS31FL3741_DRIVER_COUNT; i++) { |
| 113 | #if defined(IS31FL3741_I2C_ADDRESS_2) | 126 | is31fl3741_init(i); |
| 114 | is31fl3741_init(IS31FL3741_I2C_ADDRESS_2); | 127 | } |
| 115 | # if defined(IS31FL3741_I2C_ADDRESS_3) | ||
| 116 | is31fl3741_init(IS31FL3741_I2C_ADDRESS_3); | ||
| 117 | # if defined(IS31FL3741_I2C_ADDRESS_4) | ||
| 118 | is31fl3741_init(IS31FL3741_I2C_ADDRESS_4); | ||
| 119 | # endif | ||
| 120 | # endif | ||
| 121 | #endif | ||
| 122 | 128 | ||
| 123 | for (int i = 0; i < IS31FL3741_LED_COUNT; i++) { | 129 | for (int i = 0; i < IS31FL3741_LED_COUNT; i++) { |
| 124 | is31fl3741_set_led_control_register(i, true); | 130 | is31fl3741_set_led_control_register(i, true); |
| 125 | } | 131 | } |
| 126 | 132 | ||
| 127 | is31fl3741_update_led_control_registers(IS31FL3741_I2C_ADDRESS_1, 0); | 133 | for (uint8_t i = 0; i < IS31FL3741_DRIVER_COUNT; i++) { |
| 128 | #if defined(IS31FL3741_I2C_ADDRESS_2) | 134 | is31fl3741_update_led_control_registers(i); |
| 129 | is31fl3741_update_led_control_registers(IS31FL3741_I2C_ADDRESS_2, 1); | 135 | } |
| 130 | # if defined(IS31FL3741_I2C_ADDRESS_3) | ||
| 131 | is31fl3741_update_led_control_registers(IS31FL3741_I2C_ADDRESS_3, 2); | ||
| 132 | # if defined(IS31FL3741_I2C_ADDRESS_4) | ||
| 133 | is31fl3741_update_led_control_registers(IS31FL3741_I2C_ADDRESS_4, 3); | ||
| 134 | # endif | ||
| 135 | # endif | ||
| 136 | #endif | ||
| 137 | } | 136 | } |
| 138 | 137 | ||
| 139 | void is31fl3741_init(uint8_t addr) { | 138 | void is31fl3741_init(uint8_t index) { |
| 140 | // In order to avoid the LEDs being driven with garbage data | 139 | // In order to avoid the LEDs being driven with garbage data |
| 141 | // in the LED driver's PWM registers, shutdown is enabled last. | 140 | // in the LED driver's PWM registers, shutdown is enabled last. |
| 142 | // Set up the mode and other settings, clear the PWM registers, | 141 | // Set up the mode and other settings, clear the PWM registers, |
| 143 | // then disable software shutdown. | 142 | // then disable software shutdown. |
| 144 | // Unlock the command register. | 143 | // Unlock the command register. |
| 145 | 144 | ||
| 146 | is31fl3741_select_page(addr, IS31FL3741_COMMAND_FUNCTION); | 145 | is31fl3741_select_page(index, IS31FL3741_COMMAND_FUNCTION); |
| 147 | 146 | ||
| 148 | // Set to Normal operation | 147 | // Set to Normal operation |
| 149 | is31fl3741_write_register(addr, IS31FL3741_FUNCTION_REG_CONFIGURATION, IS31FL3741_CONFIGURATION); | 148 | is31fl3741_write_register(index, IS31FL3741_FUNCTION_REG_CONFIGURATION, IS31FL3741_CONFIGURATION); |
| 150 | 149 | ||
| 151 | // Set Golbal Current Control Register | 150 | // Set Golbal Current Control Register |
| 152 | is31fl3741_write_register(addr, IS31FL3741_FUNCTION_REG_GLOBAL_CURRENT, IS31FL3741_GLOBAL_CURRENT); | 151 | is31fl3741_write_register(index, IS31FL3741_FUNCTION_REG_GLOBAL_CURRENT, IS31FL3741_GLOBAL_CURRENT); |
| 153 | // Set Pull up & Down for SWx CSy | 152 | // Set Pull up & Down for SWx CSy |
| 154 | is31fl3741_write_register(addr, IS31FL3741_FUNCTION_REG_PULLDOWNUP, ((IS31FL3741_CS_PULLDOWN << 4) | IS31FL3741_SW_PULLUP)); | 153 | is31fl3741_write_register(index, IS31FL3741_FUNCTION_REG_PULLDOWNUP, ((IS31FL3741_CS_PULLDOWN << 4) | IS31FL3741_SW_PULLUP)); |
| 155 | // Set PWM frequency | 154 | // Set PWM frequency |
| 156 | is31fl3741_write_register(addr, IS31FL3741_FUNCTION_REG_PWM_FREQUENCY, (IS31FL3741_PWM_FREQUENCY & 0b1111)); | 155 | is31fl3741_write_register(index, IS31FL3741_FUNCTION_REG_PWM_FREQUENCY, (IS31FL3741_PWM_FREQUENCY & 0b1111)); |
| 157 | 156 | ||
| 158 | // is31fl3741_update_led_scaling_registers(addr, 0xFF, 0xFF, 0xFF); | 157 | // is31fl3741_update_led_scaling_registers(index, 0xFF, 0xFF, 0xFF); |
| 159 | 158 | ||
| 160 | // Wait 10ms to ensure the device has woken up. | 159 | // Wait 10ms to ensure the device has woken up. |
| 161 | wait_ms(10); | 160 | wait_ms(10); |
| @@ -195,11 +194,11 @@ void is31fl3741_set_led_control_register(uint8_t index, bool value) { | |||
| 195 | g_scaling_registers_update_required[led.driver] = true; | 194 | g_scaling_registers_update_required[led.driver] = true; |
| 196 | } | 195 | } |
| 197 | 196 | ||
| 198 | void is31fl3741_update_pwm_buffers(uint8_t addr, uint8_t index) { | 197 | void is31fl3741_update_pwm_buffers(uint8_t index) { |
| 199 | if (g_pwm_buffer_update_required[index]) { | 198 | if (g_pwm_buffer_update_required[index]) { |
| 200 | is31fl3741_select_page(addr, IS31FL3741_COMMAND_PWM_0); | 199 | is31fl3741_select_page(index, IS31FL3741_COMMAND_PWM_0); |
| 201 | 200 | ||
| 202 | is31fl3741_write_pwm_buffer(addr, index); | 201 | is31fl3741_write_pwm_buffer(index); |
| 203 | 202 | ||
| 204 | g_pwm_buffer_update_required[index] = false; | 203 | g_pwm_buffer_update_required[index] = false; |
| 205 | } | 204 | } |
| @@ -210,20 +209,20 @@ void is31fl3741_set_pwm_buffer(const is31fl3741_led_t *pled, uint8_t value) { | |||
| 210 | g_pwm_buffer_update_required[pled->driver] = true; | 209 | g_pwm_buffer_update_required[pled->driver] = true; |
| 211 | } | 210 | } |
| 212 | 211 | ||
| 213 | void is31fl3741_update_led_control_registers(uint8_t addr, uint8_t index) { | 212 | void is31fl3741_update_led_control_registers(uint8_t index) { |
| 214 | if (g_scaling_registers_update_required[index]) { | 213 | if (g_scaling_registers_update_required[index]) { |
| 215 | is31fl3741_select_page(addr, IS31FL3741_COMMAND_SCALING_0); | 214 | is31fl3741_select_page(index, IS31FL3741_COMMAND_SCALING_0); |
| 216 | 215 | ||
| 217 | // CS1_SW1 to CS30_SW6 are on page 2 | 216 | // CS1_SW1 to CS30_SW6 are on page 2 |
| 218 | for (int i = CS1_SW1; i <= CS30_SW6; ++i) { | 217 | for (int i = CS1_SW1; i <= CS30_SW6; ++i) { |
| 219 | is31fl3741_write_register(addr, i, g_scaling_registers[index][i]); | 218 | is31fl3741_write_register(index, i, g_scaling_registers[index][i]); |
| 220 | } | 219 | } |
| 221 | 220 | ||
| 222 | is31fl3741_select_page(addr, IS31FL3741_COMMAND_SCALING_1); | 221 | is31fl3741_select_page(index, IS31FL3741_COMMAND_SCALING_1); |
| 223 | 222 | ||
| 224 | // CS1_SW7 to CS39_SW9 are on page 3 | 223 | // CS1_SW7 to CS39_SW9 are on page 3 |
| 225 | for (int i = CS1_SW7; i <= CS39_SW9; ++i) { | 224 | for (int i = CS1_SW7; i <= CS39_SW9; ++i) { |
| 226 | is31fl3741_write_register(addr, i - CS1_SW7, g_scaling_registers[index][i]); | 225 | is31fl3741_write_register(index, i - CS1_SW7, g_scaling_registers[index][i]); |
| 227 | } | 226 | } |
| 228 | 227 | ||
| 229 | g_scaling_registers_update_required[index] = false; | 228 | g_scaling_registers_update_required[index] = false; |
| @@ -236,14 +235,7 @@ void is31fl3741_set_scaling_registers(const is31fl3741_led_t *pled, uint8_t valu | |||
| 236 | } | 235 | } |
| 237 | 236 | ||
| 238 | void is31fl3741_flush(void) { | 237 | void is31fl3741_flush(void) { |
| 239 | is31fl3741_update_pwm_buffers(IS31FL3741_I2C_ADDRESS_1, 0); | 238 | for (uint8_t i = 0; i < IS31FL3741_DRIVER_COUNT; i++) { |
| 240 | #if defined(IS31FL3741_I2C_ADDRESS_2) | 239 | is31fl3741_update_pwm_buffers(i); |
| 241 | is31fl3741_update_pwm_buffers(IS31FL3741_I2C_ADDRESS_2, 1); | 240 | } |
| 242 | # if defined(IS31FL3741_I2C_ADDRESS_3) | ||
| 243 | is31fl3741_update_pwm_buffers(IS31FL3741_I2C_ADDRESS_3, 2); | ||
| 244 | # if defined(IS31FL3741_I2C_ADDRESS_4) | ||
| 245 | is31fl3741_update_pwm_buffers(IS31FL3741_I2C_ADDRESS_4, 3); | ||
| 246 | # endif | ||
| 247 | # endif | ||
| 248 | #endif | ||
| 249 | } | 241 | } |
diff --git a/drivers/led/issi/is31fl3741-mono.h b/drivers/led/issi/is31fl3741-mono.h index d2ba1b7d17..1a5374fdce 100644 --- a/drivers/led/issi/is31fl3741-mono.h +++ b/drivers/led/issi/is31fl3741-mono.h | |||
| @@ -102,9 +102,9 @@ typedef struct is31fl3741_led_t { | |||
| 102 | extern const is31fl3741_led_t PROGMEM g_is31fl3741_leds[IS31FL3741_LED_COUNT]; | 102 | extern const is31fl3741_led_t PROGMEM g_is31fl3741_leds[IS31FL3741_LED_COUNT]; |
| 103 | 103 | ||
| 104 | void is31fl3741_init_drivers(void); | 104 | void is31fl3741_init_drivers(void); |
| 105 | void is31fl3741_init(uint8_t addr); | 105 | void is31fl3741_init(uint8_t index); |
| 106 | void is31fl3741_write_register(uint8_t addr, uint8_t reg, uint8_t data); | 106 | void is31fl3741_write_register(uint8_t index, uint8_t reg, uint8_t data); |
| 107 | void is31fl3741_select_page(uint8_t addr, uint8_t page); | 107 | void is31fl3741_select_page(uint8_t index, uint8_t page); |
| 108 | 108 | ||
| 109 | void is31fl3741_set_value(int index, uint8_t value); | 109 | void is31fl3741_set_value(int index, uint8_t value); |
| 110 | void is31fl3741_set_value_all(uint8_t value); | 110 | void is31fl3741_set_value_all(uint8_t value); |
| @@ -115,8 +115,8 @@ void is31fl3741_set_led_control_register(uint8_t index, bool value); | |||
| 115 | // (eg. from a timer interrupt). | 115 | // (eg. from a timer interrupt). |
| 116 | // Call this while idle (in between matrix scans). | 116 | // Call this while idle (in between matrix scans). |
| 117 | // If the buffer is dirty, it will update the driver with the buffer. | 117 | // If the buffer is dirty, it will update the driver with the buffer. |
| 118 | void is31fl3741_update_pwm_buffers(uint8_t addr, uint8_t index); | 118 | void is31fl3741_update_pwm_buffers(uint8_t index); |
| 119 | void is31fl3741_update_led_control_registers(uint8_t addr, uint8_t index); | 119 | void is31fl3741_update_led_control_registers(uint8_t index); |
| 120 | void is31fl3741_set_scaling_registers(const is31fl3741_led_t *pled, uint8_t value); | 120 | void is31fl3741_set_scaling_registers(const is31fl3741_led_t *pled, uint8_t value); |
| 121 | 121 | ||
| 122 | void is31fl3741_set_pwm_buffer(const is31fl3741_led_t *pled, uint8_t value); | 122 | void is31fl3741_set_pwm_buffer(const is31fl3741_led_t *pled, uint8_t value); |
diff --git a/drivers/led/issi/is31fl3741.c b/drivers/led/issi/is31fl3741.c index 5f641aa53f..de6415a851 100644 --- a/drivers/led/issi/is31fl3741.c +++ b/drivers/led/issi/is31fl3741.c | |||
| @@ -52,6 +52,19 @@ | |||
| 52 | # define IS31FL3741_GLOBAL_CURRENT 0xFF | 52 | # define IS31FL3741_GLOBAL_CURRENT 0xFF |
| 53 | #endif | 53 | #endif |
| 54 | 54 | ||
| 55 | const uint8_t i2c_addresses[IS31FL3741_DRIVER_COUNT] = { | ||
| 56 | IS31FL3741_I2C_ADDRESS_1, | ||
| 57 | #ifdef IS31FL3741_I2C_ADDRESS_2 | ||
| 58 | IS31FL3741_I2C_ADDRESS_2, | ||
| 59 | # ifdef IS31FL3741_I2C_ADDRESS_3 | ||
| 60 | IS31FL3741_I2C_ADDRESS_3, | ||
| 61 | # ifdef IS31FL3741_I2C_ADDRESS_4 | ||
| 62 | IS31FL3741_I2C_ADDRESS_4, | ||
| 63 | # endif | ||
| 64 | # endif | ||
| 65 | #endif | ||
| 66 | }; | ||
| 67 | |||
| 55 | // These buffers match the IS31FL3741 and IS31FL3741A PWM registers. | 68 | // These buffers match the IS31FL3741 and IS31FL3741A PWM registers. |
| 56 | // The scaling buffers match the page 2 and 3 LED On/Off registers. | 69 | // The scaling buffers match the page 2 and 3 LED On/Off registers. |
| 57 | // Storing them like this is optimal for I2C transfers to the registers. | 70 | // Storing them like this is optimal for I2C transfers to the registers. |
| @@ -64,98 +77,84 @@ bool g_scaling_registers_update_required[IS31FL3741_DRIVER_COUNT] = {false}; | |||
| 64 | 77 | ||
| 65 | uint8_t g_scaling_registers[IS31FL3741_DRIVER_COUNT][IS31FL3741_SCALING_REGISTER_COUNT]; | 78 | uint8_t g_scaling_registers[IS31FL3741_DRIVER_COUNT][IS31FL3741_SCALING_REGISTER_COUNT]; |
| 66 | 79 | ||
| 67 | void is31fl3741_write_register(uint8_t addr, uint8_t reg, uint8_t data) { | 80 | void is31fl3741_write_register(uint8_t index, uint8_t reg, uint8_t data) { |
| 68 | #if IS31FL3741_I2C_PERSISTENCE > 0 | 81 | #if IS31FL3741_I2C_PERSISTENCE > 0 |
| 69 | for (uint8_t i = 0; i < IS31FL3741_I2C_PERSISTENCE; i++) { | 82 | for (uint8_t i = 0; i < IS31FL3741_I2C_PERSISTENCE; i++) { |
| 70 | if (i2c_write_register(addr << 1, reg, &data, 1, IS31FL3741_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; | 83 | if (i2c_write_register(i2c_addresses[index] << 1, reg, &data, 1, IS31FL3741_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; |
| 71 | } | 84 | } |
| 72 | #else | 85 | #else |
| 73 | i2c_write_register(addr << 1, reg, &data, 1, IS31FL3741_I2C_TIMEOUT); | 86 | i2c_write_register(i2c_addresses[index] << 1, reg, &data, 1, IS31FL3741_I2C_TIMEOUT); |
| 74 | #endif | 87 | #endif |
| 75 | } | 88 | } |
| 76 | 89 | ||
| 77 | void is31fl3741_select_page(uint8_t addr, uint8_t page) { | 90 | void is31fl3741_select_page(uint8_t index, uint8_t page) { |
| 78 | is31fl3741_write_register(addr, IS31FL3741_REG_COMMAND_WRITE_LOCK, IS31FL3741_COMMAND_WRITE_LOCK_MAGIC); | 91 | is31fl3741_write_register(index, IS31FL3741_REG_COMMAND_WRITE_LOCK, IS31FL3741_COMMAND_WRITE_LOCK_MAGIC); |
| 79 | is31fl3741_write_register(addr, IS31FL3741_REG_COMMAND, page); | 92 | is31fl3741_write_register(index, IS31FL3741_REG_COMMAND, page); |
| 80 | } | 93 | } |
| 81 | 94 | ||
| 82 | void is31fl3741_write_pwm_buffer(uint8_t addr, uint8_t index) { | 95 | void is31fl3741_write_pwm_buffer(uint8_t index) { |
| 83 | // Assume page 0 is already selected | 96 | // Assume page 0 is already selected |
| 84 | 97 | ||
| 85 | for (uint16_t i = 0; i < 342; i += 18) { | 98 | for (uint16_t i = 0; i < 342; i += 18) { |
| 86 | if (i == 180) { | 99 | if (i == 180) { |
| 87 | is31fl3741_select_page(addr, IS31FL3741_COMMAND_PWM_1); | 100 | is31fl3741_select_page(index, IS31FL3741_COMMAND_PWM_1); |
| 88 | } | 101 | } |
| 89 | 102 | ||
| 90 | #if IS31FL3741_I2C_PERSISTENCE > 0 | 103 | #if IS31FL3741_I2C_PERSISTENCE > 0 |
| 91 | for (uint8_t j = 0; j < IS31FL3741_I2C_PERSISTENCE; j++) { | 104 | for (uint8_t j = 0; j < IS31FL3741_I2C_PERSISTENCE; j++) { |
| 92 | if (i2c_write_register(addr << 1, i % 180, g_pwm_buffer[index] + i, 18, IS31FL3741_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; | 105 | if (i2c_write_register(i2c_addresses[index] << 1, i % 180, g_pwm_buffer[index] + i, 18, IS31FL3741_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; |
| 93 | } | 106 | } |
| 94 | #else | 107 | #else |
| 95 | i2c_write_register(addr << 1, i % 180, g_pwm_buffer[index] + i, 18, IS31FL3741_I2C_TIMEOUT); | 108 | i2c_write_register(i2c_addresses[index] << 1, i % 180, g_pwm_buffer[index] + i, 18, IS31FL3741_I2C_TIMEOUT); |
| 96 | #endif | 109 | #endif |
| 97 | } | 110 | } |
| 98 | 111 | ||
| 99 | // transfer the left cause the total number is 351 | 112 | // transfer the left cause the total number is 351 |
| 100 | #if IS31FL3741_I2C_PERSISTENCE > 0 | 113 | #if IS31FL3741_I2C_PERSISTENCE > 0 |
| 101 | for (uint8_t i = 0; i < IS31FL3741_I2C_PERSISTENCE; i++) { | 114 | for (uint8_t i = 0; i < IS31FL3741_I2C_PERSISTENCE; i++) { |
| 102 | if (i2c_write_register(addr << 1, 162, g_pwm_buffer[index] + 342, 9, IS31FL3741_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; | 115 | if (i2c_write_register(i2c_addresses[index] << 1, 162, g_pwm_buffer[index] + 342, 9, IS31FL3741_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; |
| 103 | } | 116 | } |
| 104 | #else | 117 | #else |
| 105 | i2c_write_register(addr << 1, 162, g_pwm_buffer[index] + 342, 9, IS31FL3741_I2C_TIMEOUT); | 118 | i2c_write_register(i2c_addresses[index] << 1, 162, g_pwm_buffer[index] + 342, 9, IS31FL3741_I2C_TIMEOUT); |
| 106 | #endif | 119 | #endif |
| 107 | } | 120 | } |
| 108 | 121 | ||
| 109 | void is31fl3741_init_drivers(void) { | 122 | void is31fl3741_init_drivers(void) { |
| 110 | i2c_init(); | 123 | i2c_init(); |
| 111 | 124 | ||
| 112 | is31fl3741_init(IS31FL3741_I2C_ADDRESS_1); | 125 | for (uint8_t i = 0; i < IS31FL3741_DRIVER_COUNT; i++) { |
| 113 | #if defined(IS31FL3741_I2C_ADDRESS_2) | 126 | is31fl3741_init(i); |
| 114 | is31fl3741_init(IS31FL3741_I2C_ADDRESS_2); | 127 | } |
| 115 | # if defined(IS31FL3741_I2C_ADDRESS_3) | ||
| 116 | is31fl3741_init(IS31FL3741_I2C_ADDRESS_3); | ||
| 117 | # if defined(IS31FL3741_I2C_ADDRESS_4) | ||
| 118 | is31fl3741_init(IS31FL3741_I2C_ADDRESS_4); | ||
| 119 | # endif | ||
| 120 | # endif | ||
| 121 | #endif | ||
| 122 | 128 | ||
| 123 | for (int i = 0; i < IS31FL3741_LED_COUNT; i++) { | 129 | for (int i = 0; i < IS31FL3741_LED_COUNT; i++) { |
| 124 | is31fl3741_set_led_control_register(i, true, true, true); | 130 | is31fl3741_set_led_control_register(i, true, true, true); |
| 125 | } | 131 | } |
| 126 | 132 | ||
| 127 | is31fl3741_update_led_control_registers(IS31FL3741_I2C_ADDRESS_1, 0); | 133 | for (uint8_t i = 0; i < IS31FL3741_DRIVER_COUNT; i++) { |
| 128 | #if defined(IS31FL3741_I2C_ADDRESS_2) | 134 | is31fl3741_update_led_control_registers(i); |
| 129 | is31fl3741_update_led_control_registers(IS31FL3741_I2C_ADDRESS_2, 1); | 135 | } |
| 130 | # if defined(IS31FL3741_I2C_ADDRESS_3) | ||
| 131 | is31fl3741_update_led_control_registers(IS31FL3741_I2C_ADDRESS_3, 2); | ||
| 132 | # if defined(IS31FL3741_I2C_ADDRESS_4) | ||
| 133 | is31fl3741_update_led_control_registers(IS31FL3741_I2C_ADDRESS_4, 3); | ||
| 134 | # endif | ||
| 135 | # endif | ||
| 136 | #endif | ||
| 137 | } | 136 | } |
| 138 | 137 | ||
| 139 | void is31fl3741_init(uint8_t addr) { | 138 | void is31fl3741_init(uint8_t index) { |
| 140 | // In order to avoid the LEDs being driven with garbage data | 139 | // In order to avoid the LEDs being driven with garbage data |
| 141 | // in the LED driver's PWM registers, shutdown is enabled last. | 140 | // in the LED driver's PWM registers, shutdown is enabled last. |
| 142 | // Set up the mode and other settings, clear the PWM registers, | 141 | // Set up the mode and other settings, clear the PWM registers, |
| 143 | // then disable software shutdown. | 142 | // then disable software shutdown. |
| 144 | // Unlock the command register. | 143 | // Unlock the command register. |
| 145 | 144 | ||
| 146 | is31fl3741_select_page(addr, IS31FL3741_COMMAND_FUNCTION); | 145 | is31fl3741_select_page(index, IS31FL3741_COMMAND_FUNCTION); |
| 147 | 146 | ||
| 148 | // Set to Normal operation | 147 | // Set to Normal operation |
| 149 | is31fl3741_write_register(addr, IS31FL3741_FUNCTION_REG_CONFIGURATION, IS31FL3741_CONFIGURATION); | 148 | is31fl3741_write_register(index, IS31FL3741_FUNCTION_REG_CONFIGURATION, IS31FL3741_CONFIGURATION); |
| 150 | 149 | ||
| 151 | // Set Golbal Current Control Register | 150 | // Set Golbal Current Control Register |
| 152 | is31fl3741_write_register(addr, IS31FL3741_FUNCTION_REG_GLOBAL_CURRENT, IS31FL3741_GLOBAL_CURRENT); | 151 | is31fl3741_write_register(index, IS31FL3741_FUNCTION_REG_GLOBAL_CURRENT, IS31FL3741_GLOBAL_CURRENT); |
| 153 | // Set Pull up & Down for SWx CSy | 152 | // Set Pull up & Down for SWx CSy |
| 154 | is31fl3741_write_register(addr, IS31FL3741_FUNCTION_REG_PULLDOWNUP, ((IS31FL3741_CS_PULLDOWN << 4) | IS31FL3741_SW_PULLUP)); | 153 | is31fl3741_write_register(index, IS31FL3741_FUNCTION_REG_PULLDOWNUP, ((IS31FL3741_CS_PULLDOWN << 4) | IS31FL3741_SW_PULLUP)); |
| 155 | // Set PWM frequency | 154 | // Set PWM frequency |
| 156 | is31fl3741_write_register(addr, IS31FL3741_FUNCTION_REG_PWM_FREQUENCY, (IS31FL3741_PWM_FREQUENCY & 0b1111)); | 155 | is31fl3741_write_register(index, IS31FL3741_FUNCTION_REG_PWM_FREQUENCY, (IS31FL3741_PWM_FREQUENCY & 0b1111)); |
| 157 | 156 | ||
| 158 | // is31fl3741_update_led_scaling_registers(addr, 0xFF, 0xFF, 0xFF); | 157 | // is31fl3741_update_led_scaling_registers(index, 0xFF, 0xFF, 0xFF); |
| 159 | 158 | ||
| 160 | // Wait 10ms to ensure the device has woken up. | 159 | // Wait 10ms to ensure the device has woken up. |
| 161 | wait_ms(10); | 160 | wait_ms(10); |
| @@ -209,11 +208,11 @@ void is31fl3741_set_led_control_register(uint8_t index, bool red, bool green, bo | |||
| 209 | g_scaling_registers_update_required[led.driver] = true; | 208 | g_scaling_registers_update_required[led.driver] = true; |
| 210 | } | 209 | } |
| 211 | 210 | ||
| 212 | void is31fl3741_update_pwm_buffers(uint8_t addr, uint8_t index) { | 211 | void is31fl3741_update_pwm_buffers(uint8_t index) { |
| 213 | if (g_pwm_buffer_update_required[index]) { | 212 | if (g_pwm_buffer_update_required[index]) { |
| 214 | is31fl3741_select_page(addr, IS31FL3741_COMMAND_PWM_0); | 213 | is31fl3741_select_page(index, IS31FL3741_COMMAND_PWM_0); |
| 215 | 214 | ||
| 216 | is31fl3741_write_pwm_buffer(addr, index); | 215 | is31fl3741_write_pwm_buffer(index); |
| 217 | 216 | ||
| 218 | g_pwm_buffer_update_required[index] = false; | 217 | g_pwm_buffer_update_required[index] = false; |
| 219 | } | 218 | } |
| @@ -226,20 +225,20 @@ void is31fl3741_set_pwm_buffer(const is31fl3741_led_t *pled, uint8_t red, uint8_ | |||
| 226 | g_pwm_buffer_update_required[pled->driver] = true; | 225 | g_pwm_buffer_update_required[pled->driver] = true; |
| 227 | } | 226 | } |
| 228 | 227 | ||
| 229 | void is31fl3741_update_led_control_registers(uint8_t addr, uint8_t index) { | 228 | void is31fl3741_update_led_control_registers(uint8_t index) { |
| 230 | if (g_scaling_registers_update_required[index]) { | 229 | if (g_scaling_registers_update_required[index]) { |
| 231 | is31fl3741_select_page(addr, IS31FL3741_COMMAND_SCALING_0); | 230 | is31fl3741_select_page(index, IS31FL3741_COMMAND_SCALING_0); |
| 232 | 231 | ||
| 233 | // CS1_SW1 to CS30_SW6 are on page 2 | 232 | // CS1_SW1 to CS30_SW6 are on page 2 |
| 234 | for (int i = CS1_SW1; i <= CS30_SW6; ++i) { | 233 | for (int i = CS1_SW1; i <= CS30_SW6; ++i) { |
| 235 | is31fl3741_write_register(addr, i, g_scaling_registers[index][i]); | 234 | is31fl3741_write_register(index, i, g_scaling_registers[index][i]); |
| 236 | } | 235 | } |
| 237 | 236 | ||
| 238 | is31fl3741_select_page(addr, IS31FL3741_COMMAND_SCALING_1); | 237 | is31fl3741_select_page(index, IS31FL3741_COMMAND_SCALING_1); |
| 239 | 238 | ||
| 240 | // CS1_SW7 to CS39_SW9 are on page 3 | 239 | // CS1_SW7 to CS39_SW9 are on page 3 |
| 241 | for (int i = CS1_SW7; i <= CS39_SW9; ++i) { | 240 | for (int i = CS1_SW7; i <= CS39_SW9; ++i) { |
| 242 | is31fl3741_write_register(addr, i - CS1_SW7, g_scaling_registers[index][i]); | 241 | is31fl3741_write_register(index, i - CS1_SW7, g_scaling_registers[index][i]); |
| 243 | } | 242 | } |
| 244 | 243 | ||
| 245 | g_scaling_registers_update_required[index] = false; | 244 | g_scaling_registers_update_required[index] = false; |
| @@ -254,14 +253,7 @@ void is31fl3741_set_scaling_registers(const is31fl3741_led_t *pled, uint8_t red, | |||
| 254 | } | 253 | } |
| 255 | 254 | ||
| 256 | void is31fl3741_flush(void) { | 255 | void is31fl3741_flush(void) { |
| 257 | is31fl3741_update_pwm_buffers(IS31FL3741_I2C_ADDRESS_1, 0); | 256 | for (uint8_t i = 0; i < IS31FL3741_DRIVER_COUNT; i++) { |
| 258 | #if defined(IS31FL3741_I2C_ADDRESS_2) | 257 | is31fl3741_update_pwm_buffers(i); |
| 259 | is31fl3741_update_pwm_buffers(IS31FL3741_I2C_ADDRESS_2, 1); | 258 | } |
| 260 | # if defined(IS31FL3741_I2C_ADDRESS_3) | ||
| 261 | is31fl3741_update_pwm_buffers(IS31FL3741_I2C_ADDRESS_3, 2); | ||
| 262 | # if defined(IS31FL3741_I2C_ADDRESS_4) | ||
| 263 | is31fl3741_update_pwm_buffers(IS31FL3741_I2C_ADDRESS_4, 3); | ||
| 264 | # endif | ||
| 265 | # endif | ||
| 266 | #endif | ||
| 267 | } | 259 | } |
diff --git a/drivers/led/issi/is31fl3741.h b/drivers/led/issi/is31fl3741.h index e7777a88d5..fd8a3a5329 100644 --- a/drivers/led/issi/is31fl3741.h +++ b/drivers/led/issi/is31fl3741.h | |||
| @@ -119,9 +119,9 @@ typedef struct is31fl3741_led_t { | |||
| 119 | extern const is31fl3741_led_t PROGMEM g_is31fl3741_leds[IS31FL3741_LED_COUNT]; | 119 | extern const is31fl3741_led_t PROGMEM g_is31fl3741_leds[IS31FL3741_LED_COUNT]; |
| 120 | 120 | ||
| 121 | void is31fl3741_init_drivers(void); | 121 | void is31fl3741_init_drivers(void); |
| 122 | void is31fl3741_init(uint8_t addr); | 122 | void is31fl3741_init(uint8_t index); |
| 123 | void is31fl3741_write_register(uint8_t addr, uint8_t reg, uint8_t data); | 123 | void is31fl3741_write_register(uint8_t index, uint8_t reg, uint8_t data); |
| 124 | void is31fl3741_select_page(uint8_t addr, uint8_t page); | 124 | void is31fl3741_select_page(uint8_t index, uint8_t page); |
| 125 | 125 | ||
| 126 | void is31fl3741_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); | 126 | void is31fl3741_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); |
| 127 | void is31fl3741_set_color_all(uint8_t red, uint8_t green, uint8_t blue); | 127 | void is31fl3741_set_color_all(uint8_t red, uint8_t green, uint8_t blue); |
| @@ -132,8 +132,8 @@ void is31fl3741_set_led_control_register(uint8_t index, bool red, bool green, bo | |||
| 132 | // (eg. from a timer interrupt). | 132 | // (eg. from a timer interrupt). |
| 133 | // Call this while idle (in between matrix scans). | 133 | // Call this while idle (in between matrix scans). |
| 134 | // If the buffer is dirty, it will update the driver with the buffer. | 134 | // If the buffer is dirty, it will update the driver with the buffer. |
| 135 | void is31fl3741_update_pwm_buffers(uint8_t addr, uint8_t index); | 135 | void is31fl3741_update_pwm_buffers(uint8_t index); |
| 136 | void is31fl3741_update_led_control_registers(uint8_t addr, uint8_t index); | 136 | void is31fl3741_update_led_control_registers(uint8_t index); |
| 137 | void is31fl3741_set_scaling_registers(const is31fl3741_led_t *pled, uint8_t red, uint8_t green, uint8_t blue); | 137 | void is31fl3741_set_scaling_registers(const is31fl3741_led_t *pled, uint8_t red, uint8_t green, uint8_t blue); |
| 138 | 138 | ||
| 139 | void is31fl3741_set_pwm_buffer(const is31fl3741_led_t *pled, uint8_t red, uint8_t green, uint8_t blue); | 139 | void is31fl3741_set_pwm_buffer(const is31fl3741_led_t *pled, uint8_t red, uint8_t green, uint8_t blue); |
diff --git a/drivers/led/issi/is31fl3742a-mono.c b/drivers/led/issi/is31fl3742a-mono.c index 3a607f02d1..3bef22aabc 100644 --- a/drivers/led/issi/is31fl3742a-mono.c +++ b/drivers/led/issi/is31fl3742a-mono.c | |||
| @@ -53,28 +53,41 @@ | |||
| 53 | # define IS31FL3742A_GLOBAL_CURRENT 0xFF | 53 | # define IS31FL3742A_GLOBAL_CURRENT 0xFF |
| 54 | #endif | 54 | #endif |
| 55 | 55 | ||
| 56 | const uint8_t i2c_addresses[IS31FL3742A_DRIVER_COUNT] = { | ||
| 57 | IS31FL3742A_I2C_ADDRESS_1, | ||
| 58 | #ifdef IS31FL3742A_I2C_ADDRESS_2 | ||
| 59 | IS31FL3742A_I2C_ADDRESS_2, | ||
| 60 | # ifdef IS31FL3742A_I2C_ADDRESS_3 | ||
| 61 | IS31FL3742A_I2C_ADDRESS_3, | ||
| 62 | # ifdef IS31FL3742A_I2C_ADDRESS_4 | ||
| 63 | IS31FL3742A_I2C_ADDRESS_4, | ||
| 64 | # endif | ||
| 65 | # endif | ||
| 66 | #endif | ||
| 67 | }; | ||
| 68 | |||
| 56 | uint8_t g_pwm_buffer[IS31FL3742A_DRIVER_COUNT][IS31FL3742A_PWM_REGISTER_COUNT]; | 69 | uint8_t g_pwm_buffer[IS31FL3742A_DRIVER_COUNT][IS31FL3742A_PWM_REGISTER_COUNT]; |
| 57 | bool g_pwm_buffer_update_required[IS31FL3742A_DRIVER_COUNT] = {false}; | 70 | bool g_pwm_buffer_update_required[IS31FL3742A_DRIVER_COUNT] = {false}; |
| 58 | bool g_scaling_registers_update_required[IS31FL3742A_DRIVER_COUNT] = {false}; | 71 | bool g_scaling_registers_update_required[IS31FL3742A_DRIVER_COUNT] = {false}; |
| 59 | 72 | ||
| 60 | uint8_t g_scaling_registers[IS31FL3742A_DRIVER_COUNT][IS31FL3742A_SCALING_REGISTER_COUNT]; | 73 | uint8_t g_scaling_registers[IS31FL3742A_DRIVER_COUNT][IS31FL3742A_SCALING_REGISTER_COUNT]; |
| 61 | 74 | ||
| 62 | void is31fl3742a_write_register(uint8_t addr, uint8_t reg, uint8_t data) { | 75 | void is31fl3742a_write_register(uint8_t index, uint8_t reg, uint8_t data) { |
| 63 | #if IS31FL3742A_I2C_PERSISTENCE > 0 | 76 | #if IS31FL3742A_I2C_PERSISTENCE > 0 |
| 64 | for (uint8_t i = 0; i < IS31FL3742A_I2C_PERSISTENCE; i++) { | 77 | for (uint8_t i = 0; i < IS31FL3742A_I2C_PERSISTENCE; i++) { |
| 65 | if (i2c_write_register(addr << 1, reg, &data, 1, IS31FL3742A_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; | 78 | if (i2c_write_register(i2c_addresses[index] << 1, reg, &data, 1, IS31FL3742A_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; |
| 66 | } | 79 | } |
| 67 | #else | 80 | #else |
| 68 | i2c_write_register(addr << 1, reg, &data, 1, IS31FL3742A_I2C_TIMEOUT); | 81 | i2c_write_register(i2c_addresses[index] << 1, reg, &data, 1, IS31FL3742A_I2C_TIMEOUT); |
| 69 | #endif | 82 | #endif |
| 70 | } | 83 | } |
| 71 | 84 | ||
| 72 | void is31fl3742a_select_page(uint8_t addr, uint8_t page) { | 85 | void is31fl3742a_select_page(uint8_t index, uint8_t page) { |
| 73 | is31fl3742a_write_register(addr, IS31FL3742A_REG_COMMAND_WRITE_LOCK, IS31FL3742A_COMMAND_WRITE_LOCK_MAGIC); | 86 | is31fl3742a_write_register(index, IS31FL3742A_REG_COMMAND_WRITE_LOCK, IS31FL3742A_COMMAND_WRITE_LOCK_MAGIC); |
| 74 | is31fl3742a_write_register(addr, IS31FL3742A_REG_COMMAND, page); | 87 | is31fl3742a_write_register(index, IS31FL3742A_REG_COMMAND, page); |
| 75 | } | 88 | } |
| 76 | 89 | ||
| 77 | void is31fl3742a_write_pwm_buffer(uint8_t addr, uint8_t index) { | 90 | void is31fl3742a_write_pwm_buffer(uint8_t index) { |
| 78 | // Assumes page 0 is already selected. | 91 | // Assumes page 0 is already selected. |
| 79 | // Transmit PWM registers in 6 transfers of 30 bytes. | 92 | // Transmit PWM registers in 6 transfers of 30 bytes. |
| 80 | 93 | ||
| @@ -82,10 +95,10 @@ void is31fl3742a_write_pwm_buffer(uint8_t addr, uint8_t index) { | |||
| 82 | for (uint8_t i = 0; i < IS31FL3742A_PWM_REGISTER_COUNT; i += 30) { | 95 | for (uint8_t i = 0; i < IS31FL3742A_PWM_REGISTER_COUNT; i += 30) { |
| 83 | #if IS31FL3742A_I2C_PERSISTENCE > 0 | 96 | #if IS31FL3742A_I2C_PERSISTENCE > 0 |
| 84 | for (uint8_t j = 0; j < IS31FL3742A_I2C_PERSISTENCE; j++) { | 97 | for (uint8_t j = 0; j < IS31FL3742A_I2C_PERSISTENCE; j++) { |
| 85 | if (i2c_write_register(addr << 1, i, g_pwm_buffer[index] + i, 30, IS31FL3742A_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; | 98 | if (i2c_write_register(i2c_addresses[index] << 1, i, g_pwm_buffer[index] + i, 30, IS31FL3742A_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; |
| 86 | } | 99 | } |
| 87 | #else | 100 | #else |
| 88 | i2c_write_register(addr << 1, i, g_pwm_buffer[index] + i, 30, IS31FL3742A_I2C_TIMEOUT); | 101 | i2c_write_register(i2c_addresses[index] << 1, i, g_pwm_buffer[index] + i, 30, IS31FL3742A_I2C_TIMEOUT); |
| 89 | #endif | 102 | #endif |
| 90 | } | 103 | } |
| 91 | } | 104 | } |
| @@ -93,58 +106,44 @@ void is31fl3742a_write_pwm_buffer(uint8_t addr, uint8_t index) { | |||
| 93 | void is31fl3742a_init_drivers(void) { | 106 | void is31fl3742a_init_drivers(void) { |
| 94 | i2c_init(); | 107 | i2c_init(); |
| 95 | 108 | ||
| 96 | is31fl3742a_init(IS31FL3742A_I2C_ADDRESS_1); | 109 | for (uint8_t i = 0; i < IS31FL3742A_DRIVER_COUNT; i++) { |
| 97 | #if defined(IS31FL3742A_I2C_ADDRESS_2) | 110 | is31fl3742a_init(i); |
| 98 | is31fl3742a_init(IS31FL3742A_I2C_ADDRESS_2); | 111 | } |
| 99 | # if defined(IS31FL3742A_I2C_ADDRESS_3) | ||
| 100 | is31fl3742a_init(IS31FL3742A_I2C_ADDRESS_3); | ||
| 101 | # if defined(IS31FL3742A_I2C_ADDRESS_4) | ||
| 102 | is31fl3742a_init(IS31FL3742A_I2C_ADDRESS_4); | ||
| 103 | # endif | ||
| 104 | # endif | ||
| 105 | #endif | ||
| 106 | 112 | ||
| 107 | for (int i = 0; i < IS31FL3742A_LED_COUNT; i++) { | 113 | for (int i = 0; i < IS31FL3742A_LED_COUNT; i++) { |
| 108 | is31fl3742a_set_scaling_register(i, 0xFF); | 114 | is31fl3742a_set_scaling_register(i, 0xFF); |
| 109 | } | 115 | } |
| 110 | 116 | ||
| 111 | is31fl3742a_update_scaling_registers(IS31FL3742A_I2C_ADDRESS_1, 0); | 117 | for (uint8_t i = 0; i < IS31FL3742A_DRIVER_COUNT; i++) { |
| 112 | #if defined(IS31FL3742A_I2C_ADDRESS_2) | 118 | is31fl3742a_update_scaling_registers(i); |
| 113 | is31fl3742a_update_scaling_registers(IS31FL3742A_I2C_ADDRESS_2, 1); | 119 | } |
| 114 | # if defined(IS31FL3742A_I2C_ADDRESS_3) | ||
| 115 | is31fl3742a_update_scaling_registers(IS31FL3742A_I2C_ADDRESS_3, 2); | ||
| 116 | # if defined(IS31FL3742A_I2C_ADDRESS_4) | ||
| 117 | is31fl3742a_update_scaling_registers(IS31FL3742A_I2C_ADDRESS_4, 3); | ||
| 118 | # endif | ||
| 119 | # endif | ||
| 120 | #endif | ||
| 121 | } | 120 | } |
| 122 | 121 | ||
| 123 | void is31fl3742a_init(uint8_t addr) { | 122 | void is31fl3742a_init(uint8_t index) { |
| 124 | // In order to avoid the LEDs being driven with garbage data | 123 | // In order to avoid the LEDs being driven with garbage data |
| 125 | // in the LED driver's PWM registers, shutdown is enabled last. | 124 | // in the LED driver's PWM registers, shutdown is enabled last. |
| 126 | // Set up the mode and other settings, clear the PWM registers, | 125 | // Set up the mode and other settings, clear the PWM registers, |
| 127 | // then disable software shutdown. | 126 | // then disable software shutdown. |
| 128 | 127 | ||
| 129 | is31fl3742a_select_page(addr, IS31FL3742A_COMMAND_SCALING); | 128 | is31fl3742a_select_page(index, IS31FL3742A_COMMAND_SCALING); |
| 130 | 129 | ||
| 131 | // Turn off all LEDs. | 130 | // Turn off all LEDs. |
| 132 | for (uint8_t i = 0; i < IS31FL3742A_SCALING_REGISTER_COUNT; i++) { | 131 | for (uint8_t i = 0; i < IS31FL3742A_SCALING_REGISTER_COUNT; i++) { |
| 133 | is31fl3742a_write_register(addr, i, 0x00); | 132 | is31fl3742a_write_register(index, i, 0x00); |
| 134 | } | 133 | } |
| 135 | 134 | ||
| 136 | is31fl3742a_select_page(addr, IS31FL3742A_COMMAND_PWM); | 135 | is31fl3742a_select_page(index, IS31FL3742A_COMMAND_PWM); |
| 137 | 136 | ||
| 138 | for (uint8_t i = 0; i < IS31FL3742A_PWM_REGISTER_COUNT; i++) { | 137 | for (uint8_t i = 0; i < IS31FL3742A_PWM_REGISTER_COUNT; i++) { |
| 139 | is31fl3742a_write_register(addr, i, 0x00); | 138 | is31fl3742a_write_register(index, i, 0x00); |
| 140 | } | 139 | } |
| 141 | 140 | ||
| 142 | is31fl3742a_select_page(addr, IS31FL3742A_COMMAND_FUNCTION); | 141 | is31fl3742a_select_page(index, IS31FL3742A_COMMAND_FUNCTION); |
| 143 | 142 | ||
| 144 | is31fl3742a_write_register(addr, IS31FL3742A_FUNCTION_REG_PULLDOWNUP, (IS31FL3742A_SW_PULLDOWN << 4) | IS31FL3742A_CS_PULLUP); | 143 | is31fl3742a_write_register(index, IS31FL3742A_FUNCTION_REG_PULLDOWNUP, (IS31FL3742A_SW_PULLDOWN << 4) | IS31FL3742A_CS_PULLUP); |
| 145 | is31fl3742a_write_register(addr, IS31FL3742A_FUNCTION_REG_GLOBAL_CURRENT, IS31FL3742A_GLOBAL_CURRENT); | 144 | is31fl3742a_write_register(index, IS31FL3742A_FUNCTION_REG_GLOBAL_CURRENT, IS31FL3742A_GLOBAL_CURRENT); |
| 146 | is31fl3742a_write_register(addr, IS31FL3742A_FUNCTION_REG_PWM_FREQUENCY, (IS31FL3742A_PWM_FREQUENCY & 0b0111)); | 145 | is31fl3742a_write_register(index, IS31FL3742A_FUNCTION_REG_PWM_FREQUENCY, (IS31FL3742A_PWM_FREQUENCY & 0b0111)); |
| 147 | is31fl3742a_write_register(addr, IS31FL3742A_FUNCTION_REG_CONFIGURATION, IS31FL3742A_CONFIGURATION); | 146 | is31fl3742a_write_register(index, IS31FL3742A_FUNCTION_REG_CONFIGURATION, IS31FL3742A_CONFIGURATION); |
| 148 | 147 | ||
| 149 | // Wait 10ms to ensure the device has woken up. | 148 | // Wait 10ms to ensure the device has woken up. |
| 150 | wait_ms(10); | 149 | wait_ms(10); |
| @@ -179,22 +178,22 @@ void is31fl3742a_set_scaling_register(uint8_t index, uint8_t value) { | |||
| 179 | g_scaling_registers_update_required[led.driver] = true; | 178 | g_scaling_registers_update_required[led.driver] = true; |
| 180 | } | 179 | } |
| 181 | 180 | ||
| 182 | void is31fl3742a_update_pwm_buffers(uint8_t addr, uint8_t index) { | 181 | void is31fl3742a_update_pwm_buffers(uint8_t index) { |
| 183 | if (g_pwm_buffer_update_required[index]) { | 182 | if (g_pwm_buffer_update_required[index]) { |
| 184 | is31fl3742a_select_page(addr, IS31FL3742A_COMMAND_PWM); | 183 | is31fl3742a_select_page(index, IS31FL3742A_COMMAND_PWM); |
| 185 | 184 | ||
| 186 | is31fl3742a_write_pwm_buffer(addr, index); | 185 | is31fl3742a_write_pwm_buffer(index); |
| 187 | 186 | ||
| 188 | g_pwm_buffer_update_required[index] = false; | 187 | g_pwm_buffer_update_required[index] = false; |
| 189 | } | 188 | } |
| 190 | } | 189 | } |
| 191 | 190 | ||
| 192 | void is31fl3742a_update_scaling_registers(uint8_t addr, uint8_t index) { | 191 | void is31fl3742a_update_scaling_registers(uint8_t index) { |
| 193 | if (g_scaling_registers_update_required[index]) { | 192 | if (g_scaling_registers_update_required[index]) { |
| 194 | is31fl3742a_select_page(addr, IS31FL3742A_COMMAND_SCALING); | 193 | is31fl3742a_select_page(index, IS31FL3742A_COMMAND_SCALING); |
| 195 | 194 | ||
| 196 | for (uint8_t i = 0; i < IS31FL3742A_SCALING_REGISTER_COUNT; i++) { | 195 | for (uint8_t i = 0; i < IS31FL3742A_SCALING_REGISTER_COUNT; i++) { |
| 197 | is31fl3742a_write_register(addr, i, g_scaling_registers[index][i]); | 196 | is31fl3742a_write_register(index, i, g_scaling_registers[index][i]); |
| 198 | } | 197 | } |
| 199 | 198 | ||
| 200 | g_scaling_registers_update_required[index] = false; | 199 | g_scaling_registers_update_required[index] = false; |
| @@ -202,14 +201,7 @@ void is31fl3742a_update_scaling_registers(uint8_t addr, uint8_t index) { | |||
| 202 | } | 201 | } |
| 203 | 202 | ||
| 204 | void is31fl3742a_flush(void) { | 203 | void is31fl3742a_flush(void) { |
| 205 | is31fl3742a_update_pwm_buffers(IS31FL3742A_I2C_ADDRESS_1, 0); | 204 | for (uint8_t i = 0; i < IS31FL3742A_DRIVER_COUNT; i++) { |
| 206 | #if defined(IS31FL3742A_I2C_ADDRESS_2) | 205 | is31fl3742a_update_pwm_buffers(i); |
| 207 | is31fl3742a_update_pwm_buffers(IS31FL3742A_I2C_ADDRESS_2, 1); | 206 | } |
| 208 | # if defined(IS31FL3742A_I2C_ADDRESS_3) | ||
| 209 | is31fl3742a_update_pwm_buffers(IS31FL3742A_I2C_ADDRESS_3, 2); | ||
| 210 | # if defined(IS31FL3742A_I2C_ADDRESS_4) | ||
| 211 | is31fl3742a_update_pwm_buffers(IS31FL3742A_I2C_ADDRESS_4, 3); | ||
| 212 | # endif | ||
| 213 | # endif | ||
| 214 | #endif | ||
| 215 | } | 207 | } |
diff --git a/drivers/led/issi/is31fl3742a-mono.h b/drivers/led/issi/is31fl3742a-mono.h index 8de284fa7d..933805bc8e 100644 --- a/drivers/led/issi/is31fl3742a-mono.h +++ b/drivers/led/issi/is31fl3742a-mono.h | |||
| @@ -72,17 +72,17 @@ typedef struct is31fl3742a_led_t { | |||
| 72 | extern const is31fl3742a_led_t PROGMEM g_is31fl3742a_leds[IS31FL3742A_LED_COUNT]; | 72 | extern const is31fl3742a_led_t PROGMEM g_is31fl3742a_leds[IS31FL3742A_LED_COUNT]; |
| 73 | 73 | ||
| 74 | void is31fl3742a_init_drivers(void); | 74 | void is31fl3742a_init_drivers(void); |
| 75 | void is31fl3742a_init(uint8_t addr); | 75 | void is31fl3742a_init(uint8_t index); |
| 76 | void is31fl3742a_write_register(uint8_t addr, uint8_t reg, uint8_t data); | 76 | void is31fl3742a_write_register(uint8_t index, uint8_t reg, uint8_t data); |
| 77 | void is31fl3742a_select_page(uint8_t addr, uint8_t page); | 77 | void is31fl3742a_select_page(uint8_t index, uint8_t page); |
| 78 | 78 | ||
| 79 | void is31fl3742a_set_value(int index, uint8_t value); | 79 | void is31fl3742a_set_value(int index, uint8_t value); |
| 80 | void is31fl3742a_set_value_all(uint8_t value); | 80 | void is31fl3742a_set_value_all(uint8_t value); |
| 81 | 81 | ||
| 82 | void is31fl3742a_set_scaling_register(uint8_t index, uint8_t value); | 82 | void is31fl3742a_set_scaling_register(uint8_t index, uint8_t value); |
| 83 | 83 | ||
| 84 | void is31fl3742a_update_pwm_buffers(uint8_t addr, uint8_t index); | 84 | void is31fl3742a_update_pwm_buffers(uint8_t index); |
| 85 | void is31fl3742a_update_scaling_registers(uint8_t addr, uint8_t index); | 85 | void is31fl3742a_update_scaling_registers(uint8_t index); |
| 86 | 86 | ||
| 87 | void is31fl3742a_flush(void); | 87 | void is31fl3742a_flush(void); |
| 88 | 88 | ||
diff --git a/drivers/led/issi/is31fl3742a.c b/drivers/led/issi/is31fl3742a.c index 2e6cf151c3..1fbec5fba6 100644 --- a/drivers/led/issi/is31fl3742a.c +++ b/drivers/led/issi/is31fl3742a.c | |||
| @@ -53,28 +53,41 @@ | |||
| 53 | # define IS31FL3742A_GLOBAL_CURRENT 0xFF | 53 | # define IS31FL3742A_GLOBAL_CURRENT 0xFF |
| 54 | #endif | 54 | #endif |
| 55 | 55 | ||
| 56 | const uint8_t i2c_addresses[IS31FL3742A_DRIVER_COUNT] = { | ||
| 57 | IS31FL3742A_I2C_ADDRESS_1, | ||
| 58 | #ifdef IS31FL3742A_I2C_ADDRESS_2 | ||
| 59 | IS31FL3742A_I2C_ADDRESS_2, | ||
| 60 | # ifdef IS31FL3742A_I2C_ADDRESS_3 | ||
| 61 | IS31FL3742A_I2C_ADDRESS_3, | ||
| 62 | # ifdef IS31FL3742A_I2C_ADDRESS_4 | ||
| 63 | IS31FL3742A_I2C_ADDRESS_4, | ||
| 64 | # endif | ||
| 65 | # endif | ||
| 66 | #endif | ||
| 67 | }; | ||
| 68 | |||
| 56 | uint8_t g_pwm_buffer[IS31FL3742A_DRIVER_COUNT][IS31FL3742A_PWM_REGISTER_COUNT]; | 69 | uint8_t g_pwm_buffer[IS31FL3742A_DRIVER_COUNT][IS31FL3742A_PWM_REGISTER_COUNT]; |
| 57 | bool g_pwm_buffer_update_required[IS31FL3742A_DRIVER_COUNT] = {false}; | 70 | bool g_pwm_buffer_update_required[IS31FL3742A_DRIVER_COUNT] = {false}; |
| 58 | bool g_scaling_registers_update_required[IS31FL3742A_DRIVER_COUNT] = {false}; | 71 | bool g_scaling_registers_update_required[IS31FL3742A_DRIVER_COUNT] = {false}; |
| 59 | 72 | ||
| 60 | uint8_t g_scaling_registers[IS31FL3742A_DRIVER_COUNT][IS31FL3742A_SCALING_REGISTER_COUNT]; | 73 | uint8_t g_scaling_registers[IS31FL3742A_DRIVER_COUNT][IS31FL3742A_SCALING_REGISTER_COUNT]; |
| 61 | 74 | ||
| 62 | void is31fl3742a_write_register(uint8_t addr, uint8_t reg, uint8_t data) { | 75 | void is31fl3742a_write_register(uint8_t index, uint8_t reg, uint8_t data) { |
| 63 | #if IS31FL3742A_I2C_PERSISTENCE > 0 | 76 | #if IS31FL3742A_I2C_PERSISTENCE > 0 |
| 64 | for (uint8_t i = 0; i < IS31FL3742A_I2C_PERSISTENCE; i++) { | 77 | for (uint8_t i = 0; i < IS31FL3742A_I2C_PERSISTENCE; i++) { |
| 65 | if (i2c_write_register(addr << 1, reg, &data, 1, IS31FL3742A_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; | 78 | if (i2c_write_register(i2c_addresses[index] << 1, reg, &data, 1, IS31FL3742A_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; |
| 66 | } | 79 | } |
| 67 | #else | 80 | #else |
| 68 | i2c_write_register(addr << 1, reg, &data, 1, IS31FL3742A_I2C_TIMEOUT); | 81 | i2c_write_register(i2c_addresses[index] << 1, reg, &data, 1, IS31FL3742A_I2C_TIMEOUT); |
| 69 | #endif | 82 | #endif |
| 70 | } | 83 | } |
| 71 | 84 | ||
| 72 | void is31fl3742a_select_page(uint8_t addr, uint8_t page) { | 85 | void is31fl3742a_select_page(uint8_t index, uint8_t page) { |
| 73 | is31fl3742a_write_register(addr, IS31FL3742A_REG_COMMAND_WRITE_LOCK, IS31FL3742A_COMMAND_WRITE_LOCK_MAGIC); | 86 | is31fl3742a_write_register(index, IS31FL3742A_REG_COMMAND_WRITE_LOCK, IS31FL3742A_COMMAND_WRITE_LOCK_MAGIC); |
| 74 | is31fl3742a_write_register(addr, IS31FL3742A_REG_COMMAND, page); | 87 | is31fl3742a_write_register(index, IS31FL3742A_REG_COMMAND, page); |
| 75 | } | 88 | } |
| 76 | 89 | ||
| 77 | void is31fl3742a_write_pwm_buffer(uint8_t addr, uint8_t index) { | 90 | void is31fl3742a_write_pwm_buffer(uint8_t index) { |
| 78 | // Assumes page 0 is already selected. | 91 | // Assumes page 0 is already selected. |
| 79 | // Transmit PWM registers in 6 transfers of 30 bytes. | 92 | // Transmit PWM registers in 6 transfers of 30 bytes. |
| 80 | 93 | ||
| @@ -82,10 +95,10 @@ void is31fl3742a_write_pwm_buffer(uint8_t addr, uint8_t index) { | |||
| 82 | for (uint8_t i = 0; i < IS31FL3742A_PWM_REGISTER_COUNT; i += 30) { | 95 | for (uint8_t i = 0; i < IS31FL3742A_PWM_REGISTER_COUNT; i += 30) { |
| 83 | #if IS31FL3742A_I2C_PERSISTENCE > 0 | 96 | #if IS31FL3742A_I2C_PERSISTENCE > 0 |
| 84 | for (uint8_t j = 0; j < IS31FL3742A_I2C_PERSISTENCE; j++) { | 97 | for (uint8_t j = 0; j < IS31FL3742A_I2C_PERSISTENCE; j++) { |
| 85 | if (i2c_write_register(addr << 1, i, g_pwm_buffer[index] + i, 30, IS31FL3742A_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; | 98 | if (i2c_write_register(i2c_addresses[index] << 1, i, g_pwm_buffer[index] + i, 30, IS31FL3742A_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; |
| 86 | } | 99 | } |
| 87 | #else | 100 | #else |
| 88 | i2c_write_register(addr << 1, i, g_pwm_buffer[index] + i, 30, IS31FL3742A_I2C_TIMEOUT); | 101 | i2c_write_register(i2c_addresses[index] << 1, i, g_pwm_buffer[index] + i, 30, IS31FL3742A_I2C_TIMEOUT); |
| 89 | #endif | 102 | #endif |
| 90 | } | 103 | } |
| 91 | } | 104 | } |
| @@ -93,58 +106,44 @@ void is31fl3742a_write_pwm_buffer(uint8_t addr, uint8_t index) { | |||
| 93 | void is31fl3742a_init_drivers(void) { | 106 | void is31fl3742a_init_drivers(void) { |
| 94 | i2c_init(); | 107 | i2c_init(); |
| 95 | 108 | ||
| 96 | is31fl3742a_init(IS31FL3742A_I2C_ADDRESS_1); | 109 | for (uint8_t i = 0; i < IS31FL3742A_DRIVER_COUNT; i++) { |
| 97 | #if defined(IS31FL3742A_I2C_ADDRESS_2) | 110 | is31fl3742a_init(i); |
| 98 | is31fl3742a_init(IS31FL3742A_I2C_ADDRESS_2); | 111 | } |
| 99 | # if defined(IS31FL3742A_I2C_ADDRESS_3) | ||
| 100 | is31fl3742a_init(IS31FL3742A_I2C_ADDRESS_3); | ||
| 101 | # if defined(IS31FL3742A_I2C_ADDRESS_4) | ||
| 102 | is31fl3742a_init(IS31FL3742A_I2C_ADDRESS_4); | ||
| 103 | # endif | ||
| 104 | # endif | ||
| 105 | #endif | ||
| 106 | 112 | ||
| 107 | for (int i = 0; i < IS31FL3742A_LED_COUNT; i++) { | 113 | for (int i = 0; i < IS31FL3742A_LED_COUNT; i++) { |
| 108 | is31fl3742a_set_scaling_register(i, 0xFF, 0xFF, 0xFF); | 114 | is31fl3742a_set_scaling_register(i, 0xFF, 0xFF, 0xFF); |
| 109 | } | 115 | } |
| 110 | 116 | ||
| 111 | is31fl3742a_update_scaling_registers(IS31FL3742A_I2C_ADDRESS_1, 0); | 117 | for (uint8_t i = 0; i < IS31FL3742A_DRIVER_COUNT; i++) { |
| 112 | #if defined(IS31FL3742A_I2C_ADDRESS_2) | 118 | is31fl3742a_update_scaling_registers(i); |
| 113 | is31fl3742a_update_scaling_registers(IS31FL3742A_I2C_ADDRESS_2, 1); | 119 | } |
| 114 | # if defined(IS31FL3742A_I2C_ADDRESS_3) | ||
| 115 | is31fl3742a_update_scaling_registers(IS31FL3742A_I2C_ADDRESS_3, 2); | ||
| 116 | # if defined(IS31FL3742A_I2C_ADDRESS_4) | ||
| 117 | is31fl3742a_update_scaling_registers(IS31FL3742A_I2C_ADDRESS_4, 3); | ||
| 118 | # endif | ||
| 119 | # endif | ||
| 120 | #endif | ||
| 121 | } | 120 | } |
| 122 | 121 | ||
| 123 | void is31fl3742a_init(uint8_t addr) { | 122 | void is31fl3742a_init(uint8_t index) { |
| 124 | // In order to avoid the LEDs being driven with garbage data | 123 | // In order to avoid the LEDs being driven with garbage data |
| 125 | // in the LED driver's PWM registers, shutdown is enabled last. | 124 | // in the LED driver's PWM registers, shutdown is enabled last. |
| 126 | // Set up the mode and other settings, clear the PWM registers, | 125 | // Set up the mode and other settings, clear the PWM registers, |
| 127 | // then disable software shutdown. | 126 | // then disable software shutdown. |
| 128 | 127 | ||
| 129 | is31fl3742a_select_page(addr, IS31FL3742A_COMMAND_SCALING); | 128 | is31fl3742a_select_page(index, IS31FL3742A_COMMAND_SCALING); |
| 130 | 129 | ||
| 131 | // Turn off all LEDs. | 130 | // Turn off all LEDs. |
| 132 | for (uint8_t i = 0; i < IS31FL3742A_SCALING_REGISTER_COUNT; i++) { | 131 | for (uint8_t i = 0; i < IS31FL3742A_SCALING_REGISTER_COUNT; i++) { |
| 133 | is31fl3742a_write_register(addr, i, 0x00); | 132 | is31fl3742a_write_register(index, i, 0x00); |
| 134 | } | 133 | } |
| 135 | 134 | ||
| 136 | is31fl3742a_select_page(addr, IS31FL3742A_COMMAND_PWM); | 135 | is31fl3742a_select_page(index, IS31FL3742A_COMMAND_PWM); |
| 137 | 136 | ||
| 138 | for (uint8_t i = 0; i < IS31FL3742A_PWM_REGISTER_COUNT; i++) { | 137 | for (uint8_t i = 0; i < IS31FL3742A_PWM_REGISTER_COUNT; i++) { |
| 139 | is31fl3742a_write_register(addr, i, 0x00); | 138 | is31fl3742a_write_register(index, i, 0x00); |
| 140 | } | 139 | } |
| 141 | 140 | ||
| 142 | is31fl3742a_select_page(addr, IS31FL3742A_COMMAND_FUNCTION); | 141 | is31fl3742a_select_page(index, IS31FL3742A_COMMAND_FUNCTION); |
| 143 | 142 | ||
| 144 | is31fl3742a_write_register(addr, IS31FL3742A_FUNCTION_REG_PULLDOWNUP, (IS31FL3742A_SW_PULLDOWN << 4) | IS31FL3742A_CS_PULLUP); | 143 | is31fl3742a_write_register(index, IS31FL3742A_FUNCTION_REG_PULLDOWNUP, (IS31FL3742A_SW_PULLDOWN << 4) | IS31FL3742A_CS_PULLUP); |
| 145 | is31fl3742a_write_register(addr, IS31FL3742A_FUNCTION_REG_GLOBAL_CURRENT, IS31FL3742A_GLOBAL_CURRENT); | 144 | is31fl3742a_write_register(index, IS31FL3742A_FUNCTION_REG_GLOBAL_CURRENT, IS31FL3742A_GLOBAL_CURRENT); |
| 146 | is31fl3742a_write_register(addr, IS31FL3742A_FUNCTION_REG_PWM_FREQUENCY, (IS31FL3742A_PWM_FREQUENCY & 0b0111)); | 145 | is31fl3742a_write_register(index, IS31FL3742A_FUNCTION_REG_PWM_FREQUENCY, (IS31FL3742A_PWM_FREQUENCY & 0b0111)); |
| 147 | is31fl3742a_write_register(addr, IS31FL3742A_FUNCTION_REG_CONFIGURATION, IS31FL3742A_CONFIGURATION); | 146 | is31fl3742a_write_register(index, IS31FL3742A_FUNCTION_REG_CONFIGURATION, IS31FL3742A_CONFIGURATION); |
| 148 | 147 | ||
| 149 | // Wait 10ms to ensure the device has woken up. | 148 | // Wait 10ms to ensure the device has woken up. |
| 150 | wait_ms(10); | 149 | wait_ms(10); |
| @@ -183,22 +182,22 @@ void is31fl3742a_set_scaling_register(uint8_t index, uint8_t red, uint8_t green, | |||
| 183 | g_scaling_registers_update_required[led.driver] = true; | 182 | g_scaling_registers_update_required[led.driver] = true; |
| 184 | } | 183 | } |
| 185 | 184 | ||
| 186 | void is31fl3742a_update_pwm_buffers(uint8_t addr, uint8_t index) { | 185 | void is31fl3742a_update_pwm_buffers(uint8_t index) { |
| 187 | if (g_pwm_buffer_update_required[index]) { | 186 | if (g_pwm_buffer_update_required[index]) { |
| 188 | is31fl3742a_select_page(addr, IS31FL3742A_COMMAND_PWM); | 187 | is31fl3742a_select_page(index, IS31FL3742A_COMMAND_PWM); |
| 189 | 188 | ||
| 190 | is31fl3742a_write_pwm_buffer(addr, index); | 189 | is31fl3742a_write_pwm_buffer(index); |
| 191 | 190 | ||
| 192 | g_pwm_buffer_update_required[index] = false; | 191 | g_pwm_buffer_update_required[index] = false; |
| 193 | } | 192 | } |
| 194 | } | 193 | } |
| 195 | 194 | ||
| 196 | void is31fl3742a_update_scaling_registers(uint8_t addr, uint8_t index) { | 195 | void is31fl3742a_update_scaling_registers(uint8_t index) { |
| 197 | if (g_scaling_registers_update_required[index]) { | 196 | if (g_scaling_registers_update_required[index]) { |
| 198 | is31fl3742a_select_page(addr, IS31FL3742A_COMMAND_SCALING); | 197 | is31fl3742a_select_page(index, IS31FL3742A_COMMAND_SCALING); |
| 199 | 198 | ||
| 200 | for (uint8_t i = 0; i < IS31FL3742A_SCALING_REGISTER_COUNT; i++) { | 199 | for (uint8_t i = 0; i < IS31FL3742A_SCALING_REGISTER_COUNT; i++) { |
| 201 | is31fl3742a_write_register(addr, i, g_scaling_registers[index][i]); | 200 | is31fl3742a_write_register(index, i, g_scaling_registers[index][i]); |
| 202 | } | 201 | } |
| 203 | 202 | ||
| 204 | g_scaling_registers_update_required[index] = false; | 203 | g_scaling_registers_update_required[index] = false; |
| @@ -206,14 +205,7 @@ void is31fl3742a_update_scaling_registers(uint8_t addr, uint8_t index) { | |||
| 206 | } | 205 | } |
| 207 | 206 | ||
| 208 | void is31fl3742a_flush(void) { | 207 | void is31fl3742a_flush(void) { |
| 209 | is31fl3742a_update_pwm_buffers(IS31FL3742A_I2C_ADDRESS_1, 0); | 208 | for (uint8_t i = 0; i < IS31FL3742A_DRIVER_COUNT; i++) { |
| 210 | #if defined(IS31FL3742A_I2C_ADDRESS_2) | 209 | is31fl3742a_update_pwm_buffers(i); |
| 211 | is31fl3742a_update_pwm_buffers(IS31FL3742A_I2C_ADDRESS_2, 1); | 210 | } |
| 212 | # if defined(IS31FL3742A_I2C_ADDRESS_3) | ||
| 213 | is31fl3742a_update_pwm_buffers(IS31FL3742A_I2C_ADDRESS_3, 2); | ||
| 214 | # if defined(IS31FL3742A_I2C_ADDRESS_4) | ||
| 215 | is31fl3742a_update_pwm_buffers(IS31FL3742A_I2C_ADDRESS_4, 3); | ||
| 216 | # endif | ||
| 217 | # endif | ||
| 218 | #endif | ||
| 219 | } | 211 | } |
diff --git a/drivers/led/issi/is31fl3742a.h b/drivers/led/issi/is31fl3742a.h index 5f34a3cdb9..2d7be1488b 100644 --- a/drivers/led/issi/is31fl3742a.h +++ b/drivers/led/issi/is31fl3742a.h | |||
| @@ -74,17 +74,17 @@ typedef struct is31fl3742a_led_t { | |||
| 74 | extern const is31fl3742a_led_t PROGMEM g_is31fl3742a_leds[IS31FL3742A_LED_COUNT]; | 74 | extern const is31fl3742a_led_t PROGMEM g_is31fl3742a_leds[IS31FL3742A_LED_COUNT]; |
| 75 | 75 | ||
| 76 | void is31fl3742a_init_drivers(void); | 76 | void is31fl3742a_init_drivers(void); |
| 77 | void is31fl3742a_init(uint8_t addr); | 77 | void is31fl3742a_init(uint8_t index); |
| 78 | void is31fl3742a_write_register(uint8_t addr, uint8_t reg, uint8_t data); | 78 | void is31fl3742a_write_register(uint8_t index, uint8_t reg, uint8_t data); |
| 79 | void is31fl3742a_select_page(uint8_t addr, uint8_t page); | 79 | void is31fl3742a_select_page(uint8_t index, uint8_t page); |
| 80 | 80 | ||
| 81 | void is31fl3742a_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); | 81 | void is31fl3742a_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); |
| 82 | void is31fl3742a_set_color_all(uint8_t red, uint8_t green, uint8_t blue); | 82 | void is31fl3742a_set_color_all(uint8_t red, uint8_t green, uint8_t blue); |
| 83 | 83 | ||
| 84 | void is31fl3742a_set_scaling_register(uint8_t index, uint8_t red, uint8_t green, uint8_t blue); | 84 | void is31fl3742a_set_scaling_register(uint8_t index, uint8_t red, uint8_t green, uint8_t blue); |
| 85 | 85 | ||
| 86 | void is31fl3742a_update_pwm_buffers(uint8_t addr, uint8_t index); | 86 | void is31fl3742a_update_pwm_buffers(uint8_t index); |
| 87 | void is31fl3742a_update_scaling_registers(uint8_t addr, uint8_t index); | 87 | void is31fl3742a_update_scaling_registers(uint8_t index); |
| 88 | 88 | ||
| 89 | void is31fl3742a_flush(void); | 89 | void is31fl3742a_flush(void); |
| 90 | 90 | ||
diff --git a/drivers/led/issi/is31fl3743a-mono.c b/drivers/led/issi/is31fl3743a-mono.c index 4df0956ed2..49f5959ac8 100644 --- a/drivers/led/issi/is31fl3743a-mono.c +++ b/drivers/led/issi/is31fl3743a-mono.c | |||
| @@ -62,28 +62,54 @@ | |||
| 62 | # define IS31FL3743A_SYNC_4 IS31FL3743A_SYNC_NONE | 62 | # define IS31FL3743A_SYNC_4 IS31FL3743A_SYNC_NONE |
| 63 | #endif | 63 | #endif |
| 64 | 64 | ||
| 65 | const uint8_t i2c_addresses[IS31FL3743A_DRIVER_COUNT] = { | ||
| 66 | IS31FL3743A_I2C_ADDRESS_1, | ||
| 67 | #ifdef IS31FL3743A_I2C_ADDRESS_2 | ||
| 68 | IS31FL3743A_I2C_ADDRESS_2, | ||
| 69 | # ifdef IS31FL3743A_I2C_ADDRESS_3 | ||
| 70 | IS31FL3743A_I2C_ADDRESS_3, | ||
| 71 | # ifdef IS31FL3743A_I2C_ADDRESS_4 | ||
| 72 | IS31FL3743A_I2C_ADDRESS_4, | ||
| 73 | # endif | ||
| 74 | # endif | ||
| 75 | #endif | ||
| 76 | }; | ||
| 77 | |||
| 78 | const uint8_t driver_sync[IS31FL3743A_DRIVER_COUNT] = { | ||
| 79 | IS31FL3743A_SYNC_1, | ||
| 80 | #ifdef IS31FL3743A_I2C_ADDRESS_2 | ||
| 81 | IS31FL3743A_SYNC_2, | ||
| 82 | # ifdef IS31FL3743A_I2C_ADDRESS_3 | ||
| 83 | IS31FL3743A_SYNC_3, | ||
| 84 | # ifdef IS31FL3743A_I2C_ADDRESS_4 | ||
| 85 | IS31FL3743A_SYNC_4, | ||
| 86 | # endif | ||
| 87 | # endif | ||
| 88 | #endif | ||
| 89 | }; | ||
| 90 | |||
| 65 | uint8_t g_pwm_buffer[IS31FL3743A_DRIVER_COUNT][IS31FL3743A_PWM_REGISTER_COUNT]; | 91 | uint8_t g_pwm_buffer[IS31FL3743A_DRIVER_COUNT][IS31FL3743A_PWM_REGISTER_COUNT]; |
| 66 | bool g_pwm_buffer_update_required[IS31FL3743A_DRIVER_COUNT] = {false}; | 92 | bool g_pwm_buffer_update_required[IS31FL3743A_DRIVER_COUNT] = {false}; |
| 67 | bool g_scaling_registers_update_required[IS31FL3743A_DRIVER_COUNT] = {false}; | 93 | bool g_scaling_registers_update_required[IS31FL3743A_DRIVER_COUNT] = {false}; |
| 68 | 94 | ||
| 69 | uint8_t g_scaling_registers[IS31FL3743A_DRIVER_COUNT][IS31FL3743A_SCALING_REGISTER_COUNT]; | 95 | uint8_t g_scaling_registers[IS31FL3743A_DRIVER_COUNT][IS31FL3743A_SCALING_REGISTER_COUNT]; |
| 70 | 96 | ||
| 71 | void is31fl3743a_write_register(uint8_t addr, uint8_t reg, uint8_t data) { | 97 | void is31fl3743a_write_register(uint8_t index, uint8_t reg, uint8_t data) { |
| 72 | #if IS31FL3743A_I2C_PERSISTENCE > 0 | 98 | #if IS31FL3743A_I2C_PERSISTENCE > 0 |
| 73 | for (uint8_t i = 0; i < IS31FL3743A_I2C_PERSISTENCE; i++) { | 99 | for (uint8_t i = 0; i < IS31FL3743A_I2C_PERSISTENCE; i++) { |
| 74 | if (i2c_write_register(addr << 1, reg, &data, 1, IS31FL3743A_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; | 100 | if (i2c_write_register(i2c_addresses[index] << 1, reg, &data, 1, IS31FL3743A_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; |
| 75 | } | 101 | } |
| 76 | #else | 102 | #else |
| 77 | i2c_write_register(addr << 1, reg, &data, 1, IS31FL3743A_I2C_TIMEOUT); | 103 | i2c_write_register(i2c_addresses[index] << 1, reg, &data, 1, IS31FL3743A_I2C_TIMEOUT); |
| 78 | #endif | 104 | #endif |
| 79 | } | 105 | } |
| 80 | 106 | ||
| 81 | void is31fl3743a_select_page(uint8_t addr, uint8_t page) { | 107 | void is31fl3743a_select_page(uint8_t index, uint8_t page) { |
| 82 | is31fl3743a_write_register(addr, IS31FL3743A_REG_COMMAND_WRITE_LOCK, IS31FL3743A_COMMAND_WRITE_LOCK_MAGIC); | 108 | is31fl3743a_write_register(index, IS31FL3743A_REG_COMMAND_WRITE_LOCK, IS31FL3743A_COMMAND_WRITE_LOCK_MAGIC); |
| 83 | is31fl3743a_write_register(addr, IS31FL3743A_REG_COMMAND, page); | 109 | is31fl3743a_write_register(index, IS31FL3743A_REG_COMMAND, page); |
| 84 | } | 110 | } |
| 85 | 111 | ||
| 86 | void is31fl3743a_write_pwm_buffer(uint8_t addr, uint8_t index) { | 112 | void is31fl3743a_write_pwm_buffer(uint8_t index) { |
| 87 | // Assumes page 0 is already selected. | 113 | // Assumes page 0 is already selected. |
| 88 | // Transmit PWM registers in 11 transfers of 18 bytes. | 114 | // Transmit PWM registers in 11 transfers of 18 bytes. |
| 89 | 115 | ||
| @@ -91,10 +117,10 @@ void is31fl3743a_write_pwm_buffer(uint8_t addr, uint8_t index) { | |||
| 91 | for (uint8_t i = 0; i < IS31FL3743A_PWM_REGISTER_COUNT; i += 18) { | 117 | for (uint8_t i = 0; i < IS31FL3743A_PWM_REGISTER_COUNT; i += 18) { |
| 92 | #if IS31FL3743A_I2C_PERSISTENCE > 0 | 118 | #if IS31FL3743A_I2C_PERSISTENCE > 0 |
| 93 | for (uint8_t j = 0; j < IS31FL3743A_I2C_PERSISTENCE; j++) { | 119 | for (uint8_t j = 0; j < IS31FL3743A_I2C_PERSISTENCE; j++) { |
| 94 | if (i2c_write_register(addr << 1, i + 1, g_pwm_buffer[index] + i, 18, IS31FL3743A_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; | 120 | if (i2c_write_register(i2c_addresses[index] << 1, i + 1, g_pwm_buffer[index] + i, 18, IS31FL3743A_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; |
| 95 | } | 121 | } |
| 96 | #else | 122 | #else |
| 97 | i2c_write_register(addr << 1, i + 1, g_pwm_buffer[index] + i, 18, IS31FL3743A_I2C_TIMEOUT); | 123 | i2c_write_register(i2c_addresses[index] << 1, i + 1, g_pwm_buffer[index] + i, 18, IS31FL3743A_I2C_TIMEOUT); |
| 98 | #endif | 124 | #endif |
| 99 | } | 125 | } |
| 100 | } | 126 | } |
| @@ -102,58 +128,46 @@ void is31fl3743a_write_pwm_buffer(uint8_t addr, uint8_t index) { | |||
| 102 | void is31fl3743a_init_drivers(void) { | 128 | void is31fl3743a_init_drivers(void) { |
| 103 | i2c_init(); | 129 | i2c_init(); |
| 104 | 130 | ||
| 105 | is31fl3743a_init(IS31FL3743A_I2C_ADDRESS_1, IS31FL3743A_SYNC_1); | 131 | for (uint8_t i = 0; i < IS31FL3743A_DRIVER_COUNT; i++) { |
| 106 | #if defined(IS31FL3743A_I2C_ADDRESS_2) | 132 | is31fl3743a_init(i); |
| 107 | is31fl3743a_init(IS31FL3743A_I2C_ADDRESS_2, IS31FL3743A_SYNC_2); | 133 | } |
| 108 | # if defined(IS31FL3743A_I2C_ADDRESS_3) | ||
| 109 | is31fl3743a_init(IS31FL3743A_I2C_ADDRESS_3, IS31FL3743A_SYNC_3); | ||
| 110 | # if defined(IS31FL3743A_I2C_ADDRESS_4) | ||
| 111 | is31fl3743a_init(IS31FL3743A_I2C_ADDRESS_4, IS31FL3743A_SYNC_4); | ||
| 112 | # endif | ||
| 113 | # endif | ||
| 114 | #endif | ||
| 115 | 134 | ||
| 116 | for (int i = 0; i < IS31FL3743A_LED_COUNT; i++) { | 135 | for (int i = 0; i < IS31FL3743A_LED_COUNT; i++) { |
| 117 | is31fl3743a_set_scaling_register(i, 0xFF); | 136 | is31fl3743a_set_scaling_register(i, 0xFF); |
| 118 | } | 137 | } |
| 119 | 138 | ||
| 120 | is31fl3743a_update_scaling_registers(IS31FL3743A_I2C_ADDRESS_1, 0); | 139 | for (uint8_t i = 0; i < IS31FL3743A_DRIVER_COUNT; i++) { |
| 121 | #if defined(IS31FL3743A_I2C_ADDRESS_2) | 140 | is31fl3743a_update_scaling_registers(i); |
| 122 | is31fl3743a_update_scaling_registers(IS31FL3743A_I2C_ADDRESS_2, 1); | 141 | } |
| 123 | # if defined(IS31FL3743A_I2C_ADDRESS_3) | ||
| 124 | is31fl3743a_update_scaling_registers(IS31FL3743A_I2C_ADDRESS_3, 2); | ||
| 125 | # if defined(IS31FL3743A_I2C_ADDRESS_4) | ||
| 126 | is31fl3743a_update_scaling_registers(IS31FL3743A_I2C_ADDRESS_4, 3); | ||
| 127 | # endif | ||
| 128 | # endif | ||
| 129 | #endif | ||
| 130 | } | 142 | } |
| 131 | 143 | ||
| 132 | void is31fl3743a_init(uint8_t addr, uint8_t sync) { | 144 | void is31fl3743a_init(uint8_t index) { |
| 133 | // In order to avoid the LEDs being driven with garbage data | 145 | // In order to avoid the LEDs being driven with garbage data |
| 134 | // in the LED driver's PWM registers, shutdown is enabled last. | 146 | // in the LED driver's PWM registers, shutdown is enabled last. |
| 135 | // Set up the mode and other settings, clear the PWM registers, | 147 | // Set up the mode and other settings, clear the PWM registers, |
| 136 | // then disable software shutdown. | 148 | // then disable software shutdown. |
| 137 | 149 | ||
| 138 | is31fl3743a_select_page(addr, IS31FL3743A_COMMAND_SCALING); | 150 | is31fl3743a_select_page(index, IS31FL3743A_COMMAND_SCALING); |
| 139 | 151 | ||
| 140 | // Turn off all LEDs. | 152 | // Turn off all LEDs. |
| 141 | for (uint8_t i = 0; i < IS31FL3743A_SCALING_REGISTER_COUNT; i++) { | 153 | for (uint8_t i = 0; i < IS31FL3743A_SCALING_REGISTER_COUNT; i++) { |
| 142 | is31fl3743a_write_register(addr, i + 1, 0x00); | 154 | is31fl3743a_write_register(index, i + 1, 0x00); |
| 143 | } | 155 | } |
| 144 | 156 | ||
| 145 | is31fl3743a_select_page(addr, IS31FL3743A_COMMAND_PWM); | 157 | is31fl3743a_select_page(index, IS31FL3743A_COMMAND_PWM); |
| 146 | 158 | ||
| 147 | for (uint8_t i = 0; i < IS31FL3743A_PWM_REGISTER_COUNT; i++) { | 159 | for (uint8_t i = 0; i < IS31FL3743A_PWM_REGISTER_COUNT; i++) { |
| 148 | is31fl3743a_write_register(addr, i + 1, 0x00); | 160 | is31fl3743a_write_register(index, i + 1, 0x00); |
| 149 | } | 161 | } |
| 150 | 162 | ||
| 151 | is31fl3743a_select_page(addr, IS31FL3743A_COMMAND_FUNCTION); | 163 | is31fl3743a_select_page(index, IS31FL3743A_COMMAND_FUNCTION); |
| 152 | 164 | ||
| 153 | is31fl3743a_write_register(addr, IS31FL3743A_FUNCTION_REG_PULLDOWNUP, (IS31FL3743A_SW_PULLDOWN << 4) | IS31FL3743A_CS_PULLUP); | 165 | uint8_t sync = driver_sync[index]; |
| 154 | is31fl3743a_write_register(addr, IS31FL3743A_FUNCTION_REG_GLOBAL_CURRENT, IS31FL3743A_GLOBAL_CURRENT); | 166 | |
| 155 | is31fl3743a_write_register(addr, IS31FL3743A_FUNCTION_REG_SPREAD_SPECTRUM, (sync & 0b11) << 6); | 167 | is31fl3743a_write_register(index, IS31FL3743A_FUNCTION_REG_PULLDOWNUP, (IS31FL3743A_SW_PULLDOWN << 4) | IS31FL3743A_CS_PULLUP); |
| 156 | is31fl3743a_write_register(addr, IS31FL3743A_FUNCTION_REG_CONFIGURATION, IS31FL3743A_CONFIGURATION); | 168 | is31fl3743a_write_register(index, IS31FL3743A_FUNCTION_REG_GLOBAL_CURRENT, IS31FL3743A_GLOBAL_CURRENT); |
| 169 | is31fl3743a_write_register(index, IS31FL3743A_FUNCTION_REG_SPREAD_SPECTRUM, (sync & 0b11) << 6); | ||
| 170 | is31fl3743a_write_register(index, IS31FL3743A_FUNCTION_REG_CONFIGURATION, IS31FL3743A_CONFIGURATION); | ||
| 157 | 171 | ||
| 158 | // Wait 10ms to ensure the device has woken up. | 172 | // Wait 10ms to ensure the device has woken up. |
| 159 | wait_ms(10); | 173 | wait_ms(10); |
| @@ -188,22 +202,22 @@ void is31fl3743a_set_scaling_register(uint8_t index, uint8_t value) { | |||
| 188 | g_scaling_registers_update_required[led.driver] = true; | 202 | g_scaling_registers_update_required[led.driver] = true; |
| 189 | } | 203 | } |
| 190 | 204 | ||
| 191 | void is31fl3743a_update_pwm_buffers(uint8_t addr, uint8_t index) { | 205 | void is31fl3743a_update_pwm_buffers(uint8_t index) { |
| 192 | if (g_pwm_buffer_update_required[index]) { | 206 | if (g_pwm_buffer_update_required[index]) { |
| 193 | is31fl3743a_select_page(addr, IS31FL3743A_COMMAND_PWM); | 207 | is31fl3743a_select_page(index, IS31FL3743A_COMMAND_PWM); |
| 194 | 208 | ||
| 195 | is31fl3743a_write_pwm_buffer(addr, index); | 209 | is31fl3743a_write_pwm_buffer(index); |
| 196 | 210 | ||
| 197 | g_pwm_buffer_update_required[index] = false; | 211 | g_pwm_buffer_update_required[index] = false; |
| 198 | } | 212 | } |
| 199 | } | 213 | } |
| 200 | 214 | ||
| 201 | void is31fl3743a_update_scaling_registers(uint8_t addr, uint8_t index) { | 215 | void is31fl3743a_update_scaling_registers(uint8_t index) { |
| 202 | if (g_scaling_registers_update_required[index]) { | 216 | if (g_scaling_registers_update_required[index]) { |
| 203 | is31fl3743a_select_page(addr, IS31FL3743A_COMMAND_SCALING); | 217 | is31fl3743a_select_page(index, IS31FL3743A_COMMAND_SCALING); |
| 204 | 218 | ||
| 205 | for (uint8_t i = 0; i < IS31FL3743A_SCALING_REGISTER_COUNT; i++) { | 219 | for (uint8_t i = 0; i < IS31FL3743A_SCALING_REGISTER_COUNT; i++) { |
| 206 | is31fl3743a_write_register(addr, i + 1, g_scaling_registers[index][i]); | 220 | is31fl3743a_write_register(index, i + 1, g_scaling_registers[index][i]); |
| 207 | } | 221 | } |
| 208 | 222 | ||
| 209 | g_scaling_registers_update_required[index] = false; | 223 | g_scaling_registers_update_required[index] = false; |
| @@ -211,14 +225,7 @@ void is31fl3743a_update_scaling_registers(uint8_t addr, uint8_t index) { | |||
| 211 | } | 225 | } |
| 212 | 226 | ||
| 213 | void is31fl3743a_flush(void) { | 227 | void is31fl3743a_flush(void) { |
| 214 | is31fl3743a_update_pwm_buffers(IS31FL3743A_I2C_ADDRESS_1, 0); | 228 | for (uint8_t i = 0; i < IS31FL3743A_DRIVER_COUNT; i++) { |
| 215 | #if defined(IS31FL3743A_I2C_ADDRESS_2) | 229 | is31fl3743a_update_pwm_buffers(i); |
| 216 | is31fl3743a_update_pwm_buffers(IS31FL3743A_I2C_ADDRESS_2, 1); | 230 | } |
| 217 | # if defined(IS31FL3743A_I2C_ADDRESS_3) | ||
| 218 | is31fl3743a_update_pwm_buffers(IS31FL3743A_I2C_ADDRESS_3, 2); | ||
| 219 | # if defined(IS31FL3743A_I2C_ADDRESS_4) | ||
| 220 | is31fl3743a_update_pwm_buffers(IS31FL3743A_I2C_ADDRESS_4, 3); | ||
| 221 | # endif | ||
| 222 | # endif | ||
| 223 | #endif | ||
| 224 | } | 231 | } |
diff --git a/drivers/led/issi/is31fl3743a-mono.h b/drivers/led/issi/is31fl3743a-mono.h index 8ec3ce0755..28789c32bb 100644 --- a/drivers/led/issi/is31fl3743a-mono.h +++ b/drivers/led/issi/is31fl3743a-mono.h | |||
| @@ -82,17 +82,17 @@ typedef struct is31fl3743a_led_t { | |||
| 82 | extern const is31fl3743a_led_t PROGMEM g_is31fl3743a_leds[IS31FL3743A_LED_COUNT]; | 82 | extern const is31fl3743a_led_t PROGMEM g_is31fl3743a_leds[IS31FL3743A_LED_COUNT]; |
| 83 | 83 | ||
| 84 | void is31fl3743a_init_drivers(void); | 84 | void is31fl3743a_init_drivers(void); |
| 85 | void is31fl3743a_init(uint8_t addr, uint8_t sync); | 85 | void is31fl3743a_init(uint8_t index); |
| 86 | void is31fl3743a_write_register(uint8_t addr, uint8_t reg, uint8_t data); | 86 | void is31fl3743a_write_register(uint8_t index, uint8_t reg, uint8_t data); |
| 87 | void is31fl3743a_select_page(uint8_t addr, uint8_t page); | 87 | void is31fl3743a_select_page(uint8_t index, uint8_t page); |
| 88 | 88 | ||
| 89 | void is31fl3743a_set_value(int index, uint8_t value); | 89 | void is31fl3743a_set_value(int index, uint8_t value); |
| 90 | void is31fl3743a_set_value_all(uint8_t value); | 90 | void is31fl3743a_set_value_all(uint8_t value); |
| 91 | 91 | ||
| 92 | void is31fl3743a_set_scaling_register(uint8_t index, uint8_t value); | 92 | void is31fl3743a_set_scaling_register(uint8_t index, uint8_t value); |
| 93 | 93 | ||
| 94 | void is31fl3743a_update_pwm_buffers(uint8_t addr, uint8_t index); | 94 | void is31fl3743a_update_pwm_buffers(uint8_t index); |
| 95 | void is31fl3743a_update_scaling_registers(uint8_t addr, uint8_t index); | 95 | void is31fl3743a_update_scaling_registers(uint8_t index); |
| 96 | 96 | ||
| 97 | void is31fl3743a_flush(void); | 97 | void is31fl3743a_flush(void); |
| 98 | 98 | ||
diff --git a/drivers/led/issi/is31fl3743a.c b/drivers/led/issi/is31fl3743a.c index f9cdb130da..99f74e8743 100644 --- a/drivers/led/issi/is31fl3743a.c +++ b/drivers/led/issi/is31fl3743a.c | |||
| @@ -62,28 +62,54 @@ | |||
| 62 | # define IS31FL3743A_SYNC_4 IS31FL3743A_SYNC_NONE | 62 | # define IS31FL3743A_SYNC_4 IS31FL3743A_SYNC_NONE |
| 63 | #endif | 63 | #endif |
| 64 | 64 | ||
| 65 | const uint8_t i2c_addresses[IS31FL3743A_DRIVER_COUNT] = { | ||
| 66 | IS31FL3743A_I2C_ADDRESS_1, | ||
| 67 | #ifdef IS31FL3743A_I2C_ADDRESS_2 | ||
| 68 | IS31FL3743A_I2C_ADDRESS_2, | ||
| 69 | # ifdef IS31FL3743A_I2C_ADDRESS_3 | ||
| 70 | IS31FL3743A_I2C_ADDRESS_3, | ||
| 71 | # ifdef IS31FL3743A_I2C_ADDRESS_4 | ||
| 72 | IS31FL3743A_I2C_ADDRESS_4, | ||
| 73 | # endif | ||
| 74 | # endif | ||
| 75 | #endif | ||
| 76 | }; | ||
| 77 | |||
| 78 | const uint8_t driver_sync[IS31FL3743A_DRIVER_COUNT] = { | ||
| 79 | IS31FL3743A_SYNC_1, | ||
| 80 | #ifdef IS31FL3743A_I2C_ADDRESS_2 | ||
| 81 | IS31FL3743A_SYNC_2, | ||
| 82 | # ifdef IS31FL3743A_I2C_ADDRESS_3 | ||
| 83 | IS31FL3743A_SYNC_3, | ||
| 84 | # ifdef IS31FL3743A_I2C_ADDRESS_4 | ||
| 85 | IS31FL3743A_SYNC_4, | ||
| 86 | # endif | ||
| 87 | # endif | ||
| 88 | #endif | ||
| 89 | }; | ||
| 90 | |||
| 65 | uint8_t g_pwm_buffer[IS31FL3743A_DRIVER_COUNT][IS31FL3743A_PWM_REGISTER_COUNT]; | 91 | uint8_t g_pwm_buffer[IS31FL3743A_DRIVER_COUNT][IS31FL3743A_PWM_REGISTER_COUNT]; |
| 66 | bool g_pwm_buffer_update_required[IS31FL3743A_DRIVER_COUNT] = {false}; | 92 | bool g_pwm_buffer_update_required[IS31FL3743A_DRIVER_COUNT] = {false}; |
| 67 | bool g_scaling_registers_update_required[IS31FL3743A_DRIVER_COUNT] = {false}; | 93 | bool g_scaling_registers_update_required[IS31FL3743A_DRIVER_COUNT] = {false}; |
| 68 | 94 | ||
| 69 | uint8_t g_scaling_registers[IS31FL3743A_DRIVER_COUNT][IS31FL3743A_SCALING_REGISTER_COUNT]; | 95 | uint8_t g_scaling_registers[IS31FL3743A_DRIVER_COUNT][IS31FL3743A_SCALING_REGISTER_COUNT]; |
| 70 | 96 | ||
| 71 | void is31fl3743a_write_register(uint8_t addr, uint8_t reg, uint8_t data) { | 97 | void is31fl3743a_write_register(uint8_t index, uint8_t reg, uint8_t data) { |
| 72 | #if IS31FL3743A_I2C_PERSISTENCE > 0 | 98 | #if IS31FL3743A_I2C_PERSISTENCE > 0 |
| 73 | for (uint8_t i = 0; i < IS31FL3743A_I2C_PERSISTENCE; i++) { | 99 | for (uint8_t i = 0; i < IS31FL3743A_I2C_PERSISTENCE; i++) { |
| 74 | if (i2c_write_register(addr << 1, reg, &data, 1, IS31FL3743A_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; | 100 | if (i2c_write_register(i2c_addresses[index] << 1, reg, &data, 1, IS31FL3743A_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; |
| 75 | } | 101 | } |
| 76 | #else | 102 | #else |
| 77 | i2c_write_register(addr << 1, reg, &data, 1, IS31FL3743A_I2C_TIMEOUT); | 103 | i2c_write_register(i2c_addresses[index] << 1, reg, &data, 1, IS31FL3743A_I2C_TIMEOUT); |
| 78 | #endif | 104 | #endif |
| 79 | } | 105 | } |
| 80 | 106 | ||
| 81 | void is31fl3743a_select_page(uint8_t addr, uint8_t page) { | 107 | void is31fl3743a_select_page(uint8_t index, uint8_t page) { |
| 82 | is31fl3743a_write_register(addr, IS31FL3743A_REG_COMMAND_WRITE_LOCK, IS31FL3743A_COMMAND_WRITE_LOCK_MAGIC); | 108 | is31fl3743a_write_register(index, IS31FL3743A_REG_COMMAND_WRITE_LOCK, IS31FL3743A_COMMAND_WRITE_LOCK_MAGIC); |
| 83 | is31fl3743a_write_register(addr, IS31FL3743A_REG_COMMAND, page); | 109 | is31fl3743a_write_register(index, IS31FL3743A_REG_COMMAND, page); |
| 84 | } | 110 | } |
| 85 | 111 | ||
| 86 | void is31fl3743a_write_pwm_buffer(uint8_t addr, uint8_t index) { | 112 | void is31fl3743a_write_pwm_buffer(uint8_t index) { |
| 87 | // Assumes page 0 is already selected. | 113 | // Assumes page 0 is already selected. |
| 88 | // Transmit PWM registers in 11 transfers of 18 bytes. | 114 | // Transmit PWM registers in 11 transfers of 18 bytes. |
| 89 | 115 | ||
| @@ -91,10 +117,10 @@ void is31fl3743a_write_pwm_buffer(uint8_t addr, uint8_t index) { | |||
| 91 | for (uint8_t i = 0; i < IS31FL3743A_PWM_REGISTER_COUNT; i += 18) { | 117 | for (uint8_t i = 0; i < IS31FL3743A_PWM_REGISTER_COUNT; i += 18) { |
| 92 | #if IS31FL3743A_I2C_PERSISTENCE > 0 | 118 | #if IS31FL3743A_I2C_PERSISTENCE > 0 |
| 93 | for (uint8_t j = 0; j < IS31FL3743A_I2C_PERSISTENCE; j++) { | 119 | for (uint8_t j = 0; j < IS31FL3743A_I2C_PERSISTENCE; j++) { |
| 94 | if (i2c_write_register(addr << 1, i + 1, g_pwm_buffer[index] + i, 18, IS31FL3743A_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; | 120 | if (i2c_write_register(i2c_addresses[index] << 1, i + 1, g_pwm_buffer[index] + i, 18, IS31FL3743A_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; |
| 95 | } | 121 | } |
| 96 | #else | 122 | #else |
| 97 | i2c_write_register(addr << 1, i + 1, g_pwm_buffer[index] + i, 18, IS31FL3743A_I2C_TIMEOUT); | 123 | i2c_write_register(i2c_addresses[index] << 1, i + 1, g_pwm_buffer[index] + i, 18, IS31FL3743A_I2C_TIMEOUT); |
| 98 | #endif | 124 | #endif |
| 99 | } | 125 | } |
| 100 | } | 126 | } |
| @@ -102,58 +128,46 @@ void is31fl3743a_write_pwm_buffer(uint8_t addr, uint8_t index) { | |||
| 102 | void is31fl3743a_init_drivers(void) { | 128 | void is31fl3743a_init_drivers(void) { |
| 103 | i2c_init(); | 129 | i2c_init(); |
| 104 | 130 | ||
| 105 | is31fl3743a_init(IS31FL3743A_I2C_ADDRESS_1, IS31FL3743A_SYNC_1); | 131 | for (uint8_t i = 0; i < IS31FL3743A_DRIVER_COUNT; i++) { |
| 106 | #if defined(IS31FL3743A_I2C_ADDRESS_2) | 132 | is31fl3743a_init(i); |
| 107 | is31fl3743a_init(IS31FL3743A_I2C_ADDRESS_2, IS31FL3743A_SYNC_2); | 133 | } |
| 108 | # if defined(IS31FL3743A_I2C_ADDRESS_3) | ||
| 109 | is31fl3743a_init(IS31FL3743A_I2C_ADDRESS_3, IS31FL3743A_SYNC_3); | ||
| 110 | # if defined(IS31FL3743A_I2C_ADDRESS_4) | ||
| 111 | is31fl3743a_init(IS31FL3743A_I2C_ADDRESS_4, IS31FL3743A_SYNC_4); | ||
| 112 | # endif | ||
| 113 | # endif | ||
| 114 | #endif | ||
| 115 | 134 | ||
| 116 | for (int i = 0; i < IS31FL3743A_LED_COUNT; i++) { | 135 | for (int i = 0; i < IS31FL3743A_LED_COUNT; i++) { |
| 117 | is31fl3743a_set_scaling_register(i, 0xFF, 0xFF, 0xFF); | 136 | is31fl3743a_set_scaling_register(i, 0xFF, 0xFF, 0xFF); |
| 118 | } | 137 | } |
| 119 | 138 | ||
| 120 | is31fl3743a_update_scaling_registers(IS31FL3743A_I2C_ADDRESS_1, 0); | 139 | for (uint8_t i = 0; i < IS31FL3743A_DRIVER_COUNT; i++) { |
| 121 | #if defined(IS31FL3743A_I2C_ADDRESS_2) | 140 | is31fl3743a_update_scaling_registers(i); |
| 122 | is31fl3743a_update_scaling_registers(IS31FL3743A_I2C_ADDRESS_2, 1); | 141 | } |
| 123 | # if defined(IS31FL3743A_I2C_ADDRESS_3) | ||
| 124 | is31fl3743a_update_scaling_registers(IS31FL3743A_I2C_ADDRESS_3, 2); | ||
| 125 | # if defined(IS31FL3743A_I2C_ADDRESS_4) | ||
| 126 | is31fl3743a_update_scaling_registers(IS31FL3743A_I2C_ADDRESS_4, 3); | ||
| 127 | # endif | ||
| 128 | # endif | ||
| 129 | #endif | ||
| 130 | } | 142 | } |
| 131 | 143 | ||
| 132 | void is31fl3743a_init(uint8_t addr, uint8_t sync) { | 144 | void is31fl3743a_init(uint8_t index) { |
| 133 | // In order to avoid the LEDs being driven with garbage data | 145 | // In order to avoid the LEDs being driven with garbage data |
| 134 | // in the LED driver's PWM registers, shutdown is enabled last. | 146 | // in the LED driver's PWM registers, shutdown is enabled last. |
| 135 | // Set up the mode and other settings, clear the PWM registers, | 147 | // Set up the mode and other settings, clear the PWM registers, |
| 136 | // then disable software shutdown. | 148 | // then disable software shutdown. |
| 137 | 149 | ||
| 138 | is31fl3743a_select_page(addr, IS31FL3743A_COMMAND_SCALING); | 150 | is31fl3743a_select_page(index, IS31FL3743A_COMMAND_SCALING); |
| 139 | 151 | ||
| 140 | // Turn off all LEDs. | 152 | // Turn off all LEDs. |
| 141 | for (uint8_t i = 0; i < IS31FL3743A_SCALING_REGISTER_COUNT; i++) { | 153 | for (uint8_t i = 0; i < IS31FL3743A_SCALING_REGISTER_COUNT; i++) { |
| 142 | is31fl3743a_write_register(addr, i + 1, 0x00); | 154 | is31fl3743a_write_register(index, i + 1, 0x00); |
| 143 | } | 155 | } |
| 144 | 156 | ||
| 145 | is31fl3743a_select_page(addr, IS31FL3743A_COMMAND_PWM); | 157 | is31fl3743a_select_page(index, IS31FL3743A_COMMAND_PWM); |
| 146 | 158 | ||
| 147 | for (uint8_t i = 0; i < IS31FL3743A_PWM_REGISTER_COUNT; i++) { | 159 | for (uint8_t i = 0; i < IS31FL3743A_PWM_REGISTER_COUNT; i++) { |
| 148 | is31fl3743a_write_register(addr, i + 1, 0x00); | 160 | is31fl3743a_write_register(index, i + 1, 0x00); |
| 149 | } | 161 | } |
| 150 | 162 | ||
| 151 | is31fl3743a_select_page(addr, IS31FL3743A_COMMAND_FUNCTION); | 163 | is31fl3743a_select_page(index, IS31FL3743A_COMMAND_FUNCTION); |
| 152 | 164 | ||
| 153 | is31fl3743a_write_register(addr, IS31FL3743A_FUNCTION_REG_PULLDOWNUP, (IS31FL3743A_SW_PULLDOWN << 4) | IS31FL3743A_CS_PULLUP); | 165 | uint8_t sync = driver_sync[index]; |
| 154 | is31fl3743a_write_register(addr, IS31FL3743A_FUNCTION_REG_GLOBAL_CURRENT, IS31FL3743A_GLOBAL_CURRENT); | 166 | |
| 155 | is31fl3743a_write_register(addr, IS31FL3743A_FUNCTION_REG_SPREAD_SPECTRUM, (sync & 0b11) << 6); | 167 | is31fl3743a_write_register(index, IS31FL3743A_FUNCTION_REG_PULLDOWNUP, (IS31FL3743A_SW_PULLDOWN << 4) | IS31FL3743A_CS_PULLUP); |
| 156 | is31fl3743a_write_register(addr, IS31FL3743A_FUNCTION_REG_CONFIGURATION, IS31FL3743A_CONFIGURATION); | 168 | is31fl3743a_write_register(index, IS31FL3743A_FUNCTION_REG_GLOBAL_CURRENT, IS31FL3743A_GLOBAL_CURRENT); |
| 169 | is31fl3743a_write_register(index, IS31FL3743A_FUNCTION_REG_SPREAD_SPECTRUM, (sync & 0b11) << 6); | ||
| 170 | is31fl3743a_write_register(index, IS31FL3743A_FUNCTION_REG_CONFIGURATION, IS31FL3743A_CONFIGURATION); | ||
| 157 | 171 | ||
| 158 | // Wait 10ms to ensure the device has woken up. | 172 | // Wait 10ms to ensure the device has woken up. |
| 159 | wait_ms(10); | 173 | wait_ms(10); |
| @@ -192,22 +206,22 @@ void is31fl3743a_set_scaling_register(uint8_t index, uint8_t red, uint8_t green, | |||
| 192 | g_scaling_registers_update_required[led.driver] = true; | 206 | g_scaling_registers_update_required[led.driver] = true; |
| 193 | } | 207 | } |
| 194 | 208 | ||
| 195 | void is31fl3743a_update_pwm_buffers(uint8_t addr, uint8_t index) { | 209 | void is31fl3743a_update_pwm_buffers(uint8_t index) { |
| 196 | if (g_pwm_buffer_update_required[index]) { | 210 | if (g_pwm_buffer_update_required[index]) { |
| 197 | is31fl3743a_select_page(addr, IS31FL3743A_COMMAND_PWM); | 211 | is31fl3743a_select_page(index, IS31FL3743A_COMMAND_PWM); |
| 198 | 212 | ||
| 199 | is31fl3743a_write_pwm_buffer(addr, index); | 213 | is31fl3743a_write_pwm_buffer(index); |
| 200 | 214 | ||
| 201 | g_pwm_buffer_update_required[index] = false; | 215 | g_pwm_buffer_update_required[index] = false; |
| 202 | } | 216 | } |
| 203 | } | 217 | } |
| 204 | 218 | ||
| 205 | void is31fl3743a_update_scaling_registers(uint8_t addr, uint8_t index) { | 219 | void is31fl3743a_update_scaling_registers(uint8_t index) { |
| 206 | if (g_scaling_registers_update_required[index]) { | 220 | if (g_scaling_registers_update_required[index]) { |
| 207 | is31fl3743a_select_page(addr, IS31FL3743A_COMMAND_SCALING); | 221 | is31fl3743a_select_page(index, IS31FL3743A_COMMAND_SCALING); |
| 208 | 222 | ||
| 209 | for (uint8_t i = 0; i < IS31FL3743A_SCALING_REGISTER_COUNT; i++) { | 223 | for (uint8_t i = 0; i < IS31FL3743A_SCALING_REGISTER_COUNT; i++) { |
| 210 | is31fl3743a_write_register(addr, i + 1, g_scaling_registers[index][i]); | 224 | is31fl3743a_write_register(index, i + 1, g_scaling_registers[index][i]); |
| 211 | } | 225 | } |
| 212 | 226 | ||
| 213 | g_scaling_registers_update_required[index] = false; | 227 | g_scaling_registers_update_required[index] = false; |
| @@ -215,14 +229,7 @@ void is31fl3743a_update_scaling_registers(uint8_t addr, uint8_t index) { | |||
| 215 | } | 229 | } |
| 216 | 230 | ||
| 217 | void is31fl3743a_flush(void) { | 231 | void is31fl3743a_flush(void) { |
| 218 | is31fl3743a_update_pwm_buffers(IS31FL3743A_I2C_ADDRESS_1, 0); | 232 | for (uint8_t i = 0; i < IS31FL3743A_DRIVER_COUNT; i++) { |
| 219 | #if defined(IS31FL3743A_I2C_ADDRESS_2) | 233 | is31fl3743a_update_pwm_buffers(i); |
| 220 | is31fl3743a_update_pwm_buffers(IS31FL3743A_I2C_ADDRESS_2, 1); | 234 | } |
| 221 | # if defined(IS31FL3743A_I2C_ADDRESS_3) | ||
| 222 | is31fl3743a_update_pwm_buffers(IS31FL3743A_I2C_ADDRESS_3, 2); | ||
| 223 | # if defined(IS31FL3743A_I2C_ADDRESS_4) | ||
| 224 | is31fl3743a_update_pwm_buffers(IS31FL3743A_I2C_ADDRESS_4, 3); | ||
| 225 | # endif | ||
| 226 | # endif | ||
| 227 | #endif | ||
| 228 | } | 235 | } |
diff --git a/drivers/led/issi/is31fl3743a.h b/drivers/led/issi/is31fl3743a.h index 381b853716..416197bc0c 100644 --- a/drivers/led/issi/is31fl3743a.h +++ b/drivers/led/issi/is31fl3743a.h | |||
| @@ -84,17 +84,17 @@ typedef struct is31fl3743a_led_t { | |||
| 84 | extern const is31fl3743a_led_t PROGMEM g_is31fl3743a_leds[IS31FL3743A_LED_COUNT]; | 84 | extern const is31fl3743a_led_t PROGMEM g_is31fl3743a_leds[IS31FL3743A_LED_COUNT]; |
| 85 | 85 | ||
| 86 | void is31fl3743a_init_drivers(void); | 86 | void is31fl3743a_init_drivers(void); |
| 87 | void is31fl3743a_init(uint8_t addr, uint8_t sync); | 87 | void is31fl3743a_init(uint8_t index); |
| 88 | void is31fl3743a_write_register(uint8_t addr, uint8_t reg, uint8_t data); | 88 | void is31fl3743a_write_register(uint8_t index, uint8_t reg, uint8_t data); |
| 89 | void is31fl3743a_select_page(uint8_t addr, uint8_t page); | 89 | void is31fl3743a_select_page(uint8_t index, uint8_t page); |
| 90 | 90 | ||
| 91 | void is31fl3743a_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); | 91 | void is31fl3743a_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); |
| 92 | void is31fl3743a_set_color_all(uint8_t red, uint8_t green, uint8_t blue); | 92 | void is31fl3743a_set_color_all(uint8_t red, uint8_t green, uint8_t blue); |
| 93 | 93 | ||
| 94 | void is31fl3743a_set_scaling_register(uint8_t index, uint8_t red, uint8_t green, uint8_t blue); | 94 | void is31fl3743a_set_scaling_register(uint8_t index, uint8_t red, uint8_t green, uint8_t blue); |
| 95 | 95 | ||
| 96 | void is31fl3743a_update_pwm_buffers(uint8_t addr, uint8_t index); | 96 | void is31fl3743a_update_pwm_buffers(uint8_t index); |
| 97 | void is31fl3743a_update_scaling_registers(uint8_t addr, uint8_t index); | 97 | void is31fl3743a_update_scaling_registers(uint8_t index); |
| 98 | 98 | ||
| 99 | void is31fl3743a_flush(void); | 99 | void is31fl3743a_flush(void); |
| 100 | 100 | ||
diff --git a/drivers/led/issi/is31fl3745-mono.c b/drivers/led/issi/is31fl3745-mono.c index 2b68c96326..edb12b78bb 100644 --- a/drivers/led/issi/is31fl3745-mono.c +++ b/drivers/led/issi/is31fl3745-mono.c | |||
| @@ -62,28 +62,54 @@ | |||
| 62 | # define IS31FL3745_SYNC_4 IS31FL3745_SYNC_NONE | 62 | # define IS31FL3745_SYNC_4 IS31FL3745_SYNC_NONE |
| 63 | #endif | 63 | #endif |
| 64 | 64 | ||
| 65 | const uint8_t i2c_addresses[IS31FL3745_DRIVER_COUNT] = { | ||
| 66 | IS31FL3745_I2C_ADDRESS_1, | ||
| 67 | #ifdef IS31FL3745_I2C_ADDRESS_2 | ||
| 68 | IS31FL3745_I2C_ADDRESS_2, | ||
| 69 | # ifdef IS31FL3745_I2C_ADDRESS_3 | ||
| 70 | IS31FL3745_I2C_ADDRESS_3, | ||
| 71 | # ifdef IS31FL3745_I2C_ADDRESS_4 | ||
| 72 | IS31FL3745_I2C_ADDRESS_4, | ||
| 73 | # endif | ||
| 74 | # endif | ||
| 75 | #endif | ||
| 76 | }; | ||
| 77 | |||
| 78 | const uint8_t driver_sync[IS31FL3745_DRIVER_COUNT] = { | ||
| 79 | IS31FL3745_SYNC_1, | ||
| 80 | #ifdef IS31FL3745_I2C_ADDRESS_2 | ||
| 81 | IS31FL3745_SYNC_2, | ||
| 82 | # ifdef IS31FL3745_I2C_ADDRESS_3 | ||
| 83 | IS31FL3745_SYNC_3, | ||
| 84 | # ifdef IS31FL3745_I2C_ADDRESS_4 | ||
| 85 | IS31FL3745_SYNC_4, | ||
| 86 | # endif | ||
| 87 | # endif | ||
| 88 | #endif | ||
| 89 | }; | ||
| 90 | |||
| 65 | uint8_t g_pwm_buffer[IS31FL3745_DRIVER_COUNT][IS31FL3745_PWM_REGISTER_COUNT]; | 91 | uint8_t g_pwm_buffer[IS31FL3745_DRIVER_COUNT][IS31FL3745_PWM_REGISTER_COUNT]; |
| 66 | bool g_pwm_buffer_update_required[IS31FL3745_DRIVER_COUNT] = {false}; | 92 | bool g_pwm_buffer_update_required[IS31FL3745_DRIVER_COUNT] = {false}; |
| 67 | bool g_scaling_registers_update_required[IS31FL3745_DRIVER_COUNT] = {false}; | 93 | bool g_scaling_registers_update_required[IS31FL3745_DRIVER_COUNT] = {false}; |
| 68 | 94 | ||
| 69 | uint8_t g_scaling_registers[IS31FL3745_DRIVER_COUNT][IS31FL3745_SCALING_REGISTER_COUNT]; | 95 | uint8_t g_scaling_registers[IS31FL3745_DRIVER_COUNT][IS31FL3745_SCALING_REGISTER_COUNT]; |
| 70 | 96 | ||
| 71 | void is31fl3745_write_register(uint8_t addr, uint8_t reg, uint8_t data) { | 97 | void is31fl3745_write_register(uint8_t index, uint8_t reg, uint8_t data) { |
| 72 | #if IS31FL3745_I2C_PERSISTENCE > 0 | 98 | #if IS31FL3745_I2C_PERSISTENCE > 0 |
| 73 | for (uint8_t i = 0; i < IS31FL3745_I2C_PERSISTENCE; i++) { | 99 | for (uint8_t i = 0; i < IS31FL3745_I2C_PERSISTENCE; i++) { |
| 74 | if (i2c_write_register(addr << 1, reg, &data, 1, IS31FL3745_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; | 100 | if (i2c_write_register(i2c_addresses[index] << 1, reg, &data, 1, IS31FL3745_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; |
| 75 | } | 101 | } |
| 76 | #else | 102 | #else |
| 77 | i2c_write_register(addr << 1, reg, &data, 1, IS31FL3745_I2C_TIMEOUT); | 103 | i2c_write_register(i2c_addresses[index] << 1, reg, &data, 1, IS31FL3745_I2C_TIMEOUT); |
| 78 | #endif | 104 | #endif |
| 79 | } | 105 | } |
| 80 | 106 | ||
| 81 | void is31fl3745_select_page(uint8_t addr, uint8_t page) { | 107 | void is31fl3745_select_page(uint8_t index, uint8_t page) { |
| 82 | is31fl3745_write_register(addr, IS31FL3745_REG_COMMAND_WRITE_LOCK, IS31FL3745_COMMAND_WRITE_LOCK_MAGIC); | 108 | is31fl3745_write_register(index, IS31FL3745_REG_COMMAND_WRITE_LOCK, IS31FL3745_COMMAND_WRITE_LOCK_MAGIC); |
| 83 | is31fl3745_write_register(addr, IS31FL3745_REG_COMMAND, page); | 109 | is31fl3745_write_register(index, IS31FL3745_REG_COMMAND, page); |
| 84 | } | 110 | } |
| 85 | 111 | ||
| 86 | void is31fl3745_write_pwm_buffer(uint8_t addr, uint8_t index) { | 112 | void is31fl3745_write_pwm_buffer(uint8_t index) { |
| 87 | // Assumes page 0 is already selected. | 113 | // Assumes page 0 is already selected. |
| 88 | // Transmit PWM registers in 8 transfers of 18 bytes. | 114 | // Transmit PWM registers in 8 transfers of 18 bytes. |
| 89 | 115 | ||
| @@ -91,10 +117,10 @@ void is31fl3745_write_pwm_buffer(uint8_t addr, uint8_t index) { | |||
| 91 | for (uint8_t i = 0; i < IS31FL3745_PWM_REGISTER_COUNT; i += 18) { | 117 | for (uint8_t i = 0; i < IS31FL3745_PWM_REGISTER_COUNT; i += 18) { |
| 92 | #if IS31FL3745_I2C_PERSISTENCE > 0 | 118 | #if IS31FL3745_I2C_PERSISTENCE > 0 |
| 93 | for (uint8_t j = 0; j < IS31FL3745_I2C_PERSISTENCE; j++) { | 119 | for (uint8_t j = 0; j < IS31FL3745_I2C_PERSISTENCE; j++) { |
| 94 | if (i2c_write_register(addr << 1, i + 1, g_pwm_buffer[index] + i, 18, IS31FL3745_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; | 120 | if (i2c_write_register(i2c_addresses[index] << 1, i + 1, g_pwm_buffer[index] + i, 18, IS31FL3745_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; |
| 95 | } | 121 | } |
| 96 | #else | 122 | #else |
| 97 | i2c_write_register(addr << 1, i + 1, g_pwm_buffer[index] + i, 18, IS31FL3745_I2C_TIMEOUT); | 123 | i2c_write_register(i2c_addresses[index] << 1, i + 1, g_pwm_buffer[index] + i, 18, IS31FL3745_I2C_TIMEOUT); |
| 98 | #endif | 124 | #endif |
| 99 | } | 125 | } |
| 100 | } | 126 | } |
| @@ -102,58 +128,46 @@ void is31fl3745_write_pwm_buffer(uint8_t addr, uint8_t index) { | |||
| 102 | void is31fl3745_init_drivers(void) { | 128 | void is31fl3745_init_drivers(void) { |
| 103 | i2c_init(); | 129 | i2c_init(); |
| 104 | 130 | ||
| 105 | is31fl3745_init(IS31FL3745_I2C_ADDRESS_1, IS31FL3745_SYNC_1); | 131 | for (uint8_t i = 0; i < IS31FL3745_DRIVER_COUNT; i++) { |
| 106 | #if defined(IS31FL3745_I2C_ADDRESS_2) | 132 | is31fl3745_init(i); |
| 107 | is31fl3745_init(IS31FL3745_I2C_ADDRESS_2, IS31FL3745_SYNC_2); | 133 | } |
| 108 | # if defined(IS31FL3745_I2C_ADDRESS_3) | ||
| 109 | is31fl3745_init(IS31FL3745_I2C_ADDRESS_3, IS31FL3745_SYNC_3); | ||
| 110 | # if defined(IS31FL3745_I2C_ADDRESS_4) | ||
| 111 | is31fl3745_init(IS31FL3745_I2C_ADDRESS_4, IS31FL3745_SYNC_4); | ||
| 112 | # endif | ||
| 113 | # endif | ||
| 114 | #endif | ||
| 115 | 134 | ||
| 116 | for (int i = 0; i < IS31FL3745_LED_COUNT; i++) { | 135 | for (int i = 0; i < IS31FL3745_LED_COUNT; i++) { |
| 117 | is31fl3745_set_scaling_register(i, 0xFF); | 136 | is31fl3745_set_scaling_register(i, 0xFF); |
| 118 | } | 137 | } |
| 119 | 138 | ||
| 120 | is31fl3745_update_scaling_registers(IS31FL3745_I2C_ADDRESS_1, 0); | 139 | for (uint8_t i = 0; i < IS31FL3745_DRIVER_COUNT; i++) { |
| 121 | #if defined(IS31FL3745_I2C_ADDRESS_2) | 140 | is31fl3745_update_scaling_registers(i); |
| 122 | is31fl3745_update_scaling_registers(IS31FL3745_I2C_ADDRESS_2, 1); | 141 | } |
| 123 | # if defined(IS31FL3745_I2C_ADDRESS_3) | ||
| 124 | is31fl3745_update_scaling_registers(IS31FL3745_I2C_ADDRESS_3, 2); | ||
| 125 | # if defined(IS31FL3745_I2C_ADDRESS_4) | ||
| 126 | is31fl3745_update_scaling_registers(IS31FL3745_I2C_ADDRESS_4, 3); | ||
| 127 | # endif | ||
| 128 | # endif | ||
| 129 | #endif | ||
| 130 | } | 142 | } |
| 131 | 143 | ||
| 132 | void is31fl3745_init(uint8_t addr, uint8_t sync) { | 144 | void is31fl3745_init(uint8_t index) { |
| 133 | // In order to avoid the LEDs being driven with garbage data | 145 | // In order to avoid the LEDs being driven with garbage data |
| 134 | // in the LED driver's PWM registers, shutdown is enabled last. | 146 | // in the LED driver's PWM registers, shutdown is enabled last. |
| 135 | // Set up the mode and other settings, clear the PWM registers, | 147 | // Set up the mode and other settings, clear the PWM registers, |
| 136 | // then disable software shutdown. | 148 | // then disable software shutdown. |
| 137 | 149 | ||
| 138 | is31fl3745_select_page(addr, IS31FL3745_COMMAND_SCALING); | 150 | is31fl3745_select_page(index, IS31FL3745_COMMAND_SCALING); |
| 139 | 151 | ||
| 140 | // Turn off all LEDs. | 152 | // Turn off all LEDs. |
| 141 | for (uint8_t i = 0; i < IS31FL3745_SCALING_REGISTER_COUNT; i++) { | 153 | for (uint8_t i = 0; i < IS31FL3745_SCALING_REGISTER_COUNT; i++) { |
| 142 | is31fl3745_write_register(addr, i + 1, 0x00); | 154 | is31fl3745_write_register(index, i + 1, 0x00); |
| 143 | } | 155 | } |
| 144 | 156 | ||
| 145 | is31fl3745_select_page(addr, IS31FL3745_COMMAND_PWM); | 157 | is31fl3745_select_page(index, IS31FL3745_COMMAND_PWM); |
| 146 | 158 | ||
| 147 | for (uint8_t i = 0; i < IS31FL3745_PWM_REGISTER_COUNT; i++) { | 159 | for (uint8_t i = 0; i < IS31FL3745_PWM_REGISTER_COUNT; i++) { |
| 148 | is31fl3745_write_register(addr, i + 1, 0x00); | 160 | is31fl3745_write_register(index, i + 1, 0x00); |
| 149 | } | 161 | } |
| 150 | 162 | ||
| 151 | is31fl3745_select_page(addr, IS31FL3745_COMMAND_FUNCTION); | 163 | is31fl3745_select_page(index, IS31FL3745_COMMAND_FUNCTION); |
| 152 | 164 | ||
| 153 | is31fl3745_write_register(addr, IS31FL3745_FUNCTION_REG_PULLDOWNUP, (IS31FL3745_SW_PULLDOWN << 4) | IS31FL3745_CS_PULLUP); | 165 | uint8_t sync = driver_sync[index]; |
| 154 | is31fl3745_write_register(addr, IS31FL3745_FUNCTION_REG_GLOBAL_CURRENT, IS31FL3745_GLOBAL_CURRENT); | 166 | |
| 155 | is31fl3745_write_register(addr, IS31FL3745_FUNCTION_REG_SPREAD_SPECTRUM, (sync & 0b11) << 6); | 167 | is31fl3745_write_register(index, IS31FL3745_FUNCTION_REG_PULLDOWNUP, (IS31FL3745_SW_PULLDOWN << 4) | IS31FL3745_CS_PULLUP); |
| 156 | is31fl3745_write_register(addr, IS31FL3745_FUNCTION_REG_CONFIGURATION, IS31FL3745_CONFIGURATION); | 168 | is31fl3745_write_register(index, IS31FL3745_FUNCTION_REG_GLOBAL_CURRENT, IS31FL3745_GLOBAL_CURRENT); |
| 169 | is31fl3745_write_register(index, IS31FL3745_FUNCTION_REG_SPREAD_SPECTRUM, (sync & 0b11) << 6); | ||
| 170 | is31fl3745_write_register(index, IS31FL3745_FUNCTION_REG_CONFIGURATION, IS31FL3745_CONFIGURATION); | ||
| 157 | 171 | ||
| 158 | // Wait 10ms to ensure the device has woken up. | 172 | // Wait 10ms to ensure the device has woken up. |
| 159 | wait_ms(10); | 173 | wait_ms(10); |
| @@ -188,22 +202,22 @@ void is31fl3745_set_scaling_register(uint8_t index, uint8_t value) { | |||
| 188 | g_scaling_registers_update_required[led.driver] = true; | 202 | g_scaling_registers_update_required[led.driver] = true; |
| 189 | } | 203 | } |
| 190 | 204 | ||
| 191 | void is31fl3745_update_pwm_buffers(uint8_t addr, uint8_t index) { | 205 | void is31fl3745_update_pwm_buffers(uint8_t index) { |
| 192 | if (g_pwm_buffer_update_required[index]) { | 206 | if (g_pwm_buffer_update_required[index]) { |
| 193 | is31fl3745_select_page(addr, IS31FL3745_COMMAND_PWM); | 207 | is31fl3745_select_page(index, IS31FL3745_COMMAND_PWM); |
| 194 | 208 | ||
| 195 | is31fl3745_write_pwm_buffer(addr, index); | 209 | is31fl3745_write_pwm_buffer(index); |
| 196 | 210 | ||
| 197 | g_pwm_buffer_update_required[index] = false; | 211 | g_pwm_buffer_update_required[index] = false; |
| 198 | } | 212 | } |
| 199 | } | 213 | } |
| 200 | 214 | ||
| 201 | void is31fl3745_update_scaling_registers(uint8_t addr, uint8_t index) { | 215 | void is31fl3745_update_scaling_registers(uint8_t index) { |
| 202 | if (g_scaling_registers_update_required[index]) { | 216 | if (g_scaling_registers_update_required[index]) { |
| 203 | is31fl3745_select_page(addr, IS31FL3745_COMMAND_SCALING); | 217 | is31fl3745_select_page(index, IS31FL3745_COMMAND_SCALING); |
| 204 | 218 | ||
| 205 | for (uint8_t i = 0; i < IS31FL3745_SCALING_REGISTER_COUNT; i++) { | 219 | for (uint8_t i = 0; i < IS31FL3745_SCALING_REGISTER_COUNT; i++) { |
| 206 | is31fl3745_write_register(addr, i + 1, g_scaling_registers[index][i]); | 220 | is31fl3745_write_register(index, i + 1, g_scaling_registers[index][i]); |
| 207 | } | 221 | } |
| 208 | 222 | ||
| 209 | g_scaling_registers_update_required[index] = false; | 223 | g_scaling_registers_update_required[index] = false; |
| @@ -211,14 +225,7 @@ void is31fl3745_update_scaling_registers(uint8_t addr, uint8_t index) { | |||
| 211 | } | 225 | } |
| 212 | 226 | ||
| 213 | void is31fl3745_flush(void) { | 227 | void is31fl3745_flush(void) { |
| 214 | is31fl3745_update_pwm_buffers(IS31FL3745_I2C_ADDRESS_1, 0); | 228 | for (uint8_t i = 0; i < IS31FL3745_DRIVER_COUNT; i++) { |
| 215 | #if defined(IS31FL3745_I2C_ADDRESS_2) | 229 | is31fl3745_update_pwm_buffers(i); |
| 216 | is31fl3745_update_pwm_buffers(IS31FL3745_I2C_ADDRESS_2, 1); | 230 | } |
| 217 | # if defined(IS31FL3745_I2C_ADDRESS_3) | ||
| 218 | is31fl3745_update_pwm_buffers(IS31FL3745_I2C_ADDRESS_3, 2); | ||
| 219 | # if defined(IS31FL3745_I2C_ADDRESS_4) | ||
| 220 | is31fl3745_update_pwm_buffers(IS31FL3745_I2C_ADDRESS_4, 3); | ||
| 221 | # endif | ||
| 222 | # endif | ||
| 223 | #endif | ||
| 224 | } | 231 | } |
diff --git a/drivers/led/issi/is31fl3745-mono.h b/drivers/led/issi/is31fl3745-mono.h index f60f0acfd9..02d926cd7d 100644 --- a/drivers/led/issi/is31fl3745-mono.h +++ b/drivers/led/issi/is31fl3745-mono.h | |||
| @@ -82,17 +82,17 @@ typedef struct is31fl3745_led_t { | |||
| 82 | extern const is31fl3745_led_t PROGMEM g_is31fl3745_leds[IS31FL3745_LED_COUNT]; | 82 | extern const is31fl3745_led_t PROGMEM g_is31fl3745_leds[IS31FL3745_LED_COUNT]; |
| 83 | 83 | ||
| 84 | void is31fl3745_init_drivers(void); | 84 | void is31fl3745_init_drivers(void); |
| 85 | void is31fl3745_init(uint8_t addr, uint8_t sync); | 85 | void is31fl3745_init(uint8_t index); |
| 86 | void is31fl3745_write_register(uint8_t addr, uint8_t reg, uint8_t data); | 86 | void is31fl3745_write_register(uint8_t index, uint8_t reg, uint8_t data); |
| 87 | void is31fl3745_select_page(uint8_t addr, uint8_t page); | 87 | void is31fl3745_select_page(uint8_t index, uint8_t page); |
| 88 | 88 | ||
| 89 | void is31fl3745_set_value(int index, uint8_t value); | 89 | void is31fl3745_set_value(int index, uint8_t value); |
| 90 | void is31fl3745_set_value_all(uint8_t value); | 90 | void is31fl3745_set_value_all(uint8_t value); |
| 91 | 91 | ||
| 92 | void is31fl3745_set_scaling_register(uint8_t index, uint8_t value); | 92 | void is31fl3745_set_scaling_register(uint8_t index, uint8_t value); |
| 93 | 93 | ||
| 94 | void is31fl3745_update_pwm_buffers(uint8_t addr, uint8_t index); | 94 | void is31fl3745_update_pwm_buffers(uint8_t index); |
| 95 | void is31fl3745_update_scaling_registers(uint8_t addr, uint8_t index); | 95 | void is31fl3745_update_scaling_registers(uint8_t index); |
| 96 | 96 | ||
| 97 | void is31fl3745_flush(void); | 97 | void is31fl3745_flush(void); |
| 98 | 98 | ||
diff --git a/drivers/led/issi/is31fl3745.c b/drivers/led/issi/is31fl3745.c index 0f91a75bcc..3a67f6819a 100644 --- a/drivers/led/issi/is31fl3745.c +++ b/drivers/led/issi/is31fl3745.c | |||
| @@ -62,28 +62,54 @@ | |||
| 62 | # define IS31FL3745_SYNC_4 IS31FL3745_SYNC_NONE | 62 | # define IS31FL3745_SYNC_4 IS31FL3745_SYNC_NONE |
| 63 | #endif | 63 | #endif |
| 64 | 64 | ||
| 65 | const uint8_t i2c_addresses[IS31FL3745_DRIVER_COUNT] = { | ||
| 66 | IS31FL3745_I2C_ADDRESS_1, | ||
| 67 | #ifdef IS31FL3745_I2C_ADDRESS_2 | ||
| 68 | IS31FL3745_I2C_ADDRESS_2, | ||
| 69 | # ifdef IS31FL3745_I2C_ADDRESS_3 | ||
| 70 | IS31FL3745_I2C_ADDRESS_3, | ||
| 71 | # ifdef IS31FL3745_I2C_ADDRESS_4 | ||
| 72 | IS31FL3745_I2C_ADDRESS_4, | ||
| 73 | # endif | ||
| 74 | # endif | ||
| 75 | #endif | ||
| 76 | }; | ||
| 77 | |||
| 78 | const uint8_t driver_sync[IS31FL3745_DRIVER_COUNT] = { | ||
| 79 | IS31FL3745_SYNC_1, | ||
| 80 | #ifdef IS31FL3745_I2C_ADDRESS_2 | ||
| 81 | IS31FL3745_SYNC_2, | ||
| 82 | # ifdef IS31FL3745_I2C_ADDRESS_3 | ||
| 83 | IS31FL3745_SYNC_3, | ||
| 84 | # ifdef IS31FL3745_I2C_ADDRESS_4 | ||
| 85 | IS31FL3745_SYNC_4, | ||
| 86 | # endif | ||
| 87 | # endif | ||
| 88 | #endif | ||
| 89 | }; | ||
| 90 | |||
| 65 | uint8_t g_pwm_buffer[IS31FL3745_DRIVER_COUNT][IS31FL3745_PWM_REGISTER_COUNT]; | 91 | uint8_t g_pwm_buffer[IS31FL3745_DRIVER_COUNT][IS31FL3745_PWM_REGISTER_COUNT]; |
| 66 | bool g_pwm_buffer_update_required[IS31FL3745_DRIVER_COUNT] = {false}; | 92 | bool g_pwm_buffer_update_required[IS31FL3745_DRIVER_COUNT] = {false}; |
| 67 | bool g_scaling_registers_update_required[IS31FL3745_DRIVER_COUNT] = {false}; | 93 | bool g_scaling_registers_update_required[IS31FL3745_DRIVER_COUNT] = {false}; |
| 68 | 94 | ||
| 69 | uint8_t g_scaling_registers[IS31FL3745_DRIVER_COUNT][IS31FL3745_SCALING_REGISTER_COUNT]; | 95 | uint8_t g_scaling_registers[IS31FL3745_DRIVER_COUNT][IS31FL3745_SCALING_REGISTER_COUNT]; |
| 70 | 96 | ||
| 71 | void is31fl3745_write_register(uint8_t addr, uint8_t reg, uint8_t data) { | 97 | void is31fl3745_write_register(uint8_t index, uint8_t reg, uint8_t data) { |
| 72 | #if IS31FL3745_I2C_PERSISTENCE > 0 | 98 | #if IS31FL3745_I2C_PERSISTENCE > 0 |
| 73 | for (uint8_t i = 0; i < IS31FL3745_I2C_PERSISTENCE; i++) { | 99 | for (uint8_t i = 0; i < IS31FL3745_I2C_PERSISTENCE; i++) { |
| 74 | if (i2c_write_register(addr << 1, reg, &data, 1, IS31FL3745_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; | 100 | if (i2c_write_register(i2c_addresses[index] << 1, reg, &data, 1, IS31FL3745_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; |
| 75 | } | 101 | } |
| 76 | #else | 102 | #else |
| 77 | i2c_write_register(addr << 1, reg, &data, 1, IS31FL3745_I2C_TIMEOUT); | 103 | i2c_write_register(i2c_addresses[index] << 1, reg, &data, 1, IS31FL3745_I2C_TIMEOUT); |
| 78 | #endif | 104 | #endif |
| 79 | } | 105 | } |
| 80 | 106 | ||
| 81 | void is31fl3745_select_page(uint8_t addr, uint8_t page) { | 107 | void is31fl3745_select_page(uint8_t index, uint8_t page) { |
| 82 | is31fl3745_write_register(addr, IS31FL3745_REG_COMMAND_WRITE_LOCK, IS31FL3745_COMMAND_WRITE_LOCK_MAGIC); | 108 | is31fl3745_write_register(index, IS31FL3745_REG_COMMAND_WRITE_LOCK, IS31FL3745_COMMAND_WRITE_LOCK_MAGIC); |
| 83 | is31fl3745_write_register(addr, IS31FL3745_REG_COMMAND, page); | 109 | is31fl3745_write_register(index, IS31FL3745_REG_COMMAND, page); |
| 84 | } | 110 | } |
| 85 | 111 | ||
| 86 | void is31fl3745_write_pwm_buffer(uint8_t addr, uint8_t index) { | 112 | void is31fl3745_write_pwm_buffer(uint8_t index) { |
| 87 | // Assumes page 0 is already selected. | 113 | // Assumes page 0 is already selected. |
| 88 | // Transmit PWM registers in 8 transfers of 18 bytes. | 114 | // Transmit PWM registers in 8 transfers of 18 bytes. |
| 89 | 115 | ||
| @@ -91,10 +117,10 @@ void is31fl3745_write_pwm_buffer(uint8_t addr, uint8_t index) { | |||
| 91 | for (uint8_t i = 0; i < IS31FL3745_PWM_REGISTER_COUNT; i += 18) { | 117 | for (uint8_t i = 0; i < IS31FL3745_PWM_REGISTER_COUNT; i += 18) { |
| 92 | #if IS31FL3745_I2C_PERSISTENCE > 0 | 118 | #if IS31FL3745_I2C_PERSISTENCE > 0 |
| 93 | for (uint8_t j = 0; j < IS31FL3745_I2C_PERSISTENCE; j++) { | 119 | for (uint8_t j = 0; j < IS31FL3745_I2C_PERSISTENCE; j++) { |
| 94 | if (i2c_write_register(addr << 1, i + 1, g_pwm_buffer[index] + i, 18, IS31FL3745_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; | 120 | if (i2c_write_register(i2c_addresses[index] << 1, i + 1, g_pwm_buffer[index] + i, 18, IS31FL3745_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; |
| 95 | } | 121 | } |
| 96 | #else | 122 | #else |
| 97 | i2c_write_register(addr << 1, i + 1, g_pwm_buffer[index] + i, 18, IS31FL3745_I2C_TIMEOUT); | 123 | i2c_write_register(i2c_addresses[index] << 1, i + 1, g_pwm_buffer[index] + i, 18, IS31FL3745_I2C_TIMEOUT); |
| 98 | #endif | 124 | #endif |
| 99 | } | 125 | } |
| 100 | } | 126 | } |
| @@ -102,58 +128,46 @@ void is31fl3745_write_pwm_buffer(uint8_t addr, uint8_t index) { | |||
| 102 | void is31fl3745_init_drivers(void) { | 128 | void is31fl3745_init_drivers(void) { |
| 103 | i2c_init(); | 129 | i2c_init(); |
| 104 | 130 | ||
| 105 | is31fl3745_init(IS31FL3745_I2C_ADDRESS_1, IS31FL3745_SYNC_1); | 131 | for (uint8_t i = 0; i < IS31FL3745_DRIVER_COUNT; i++) { |
| 106 | #if defined(IS31FL3745_I2C_ADDRESS_2) | 132 | is31fl3745_init(i); |
| 107 | is31fl3745_init(IS31FL3745_I2C_ADDRESS_2, IS31FL3745_SYNC_2); | 133 | } |
| 108 | # if defined(IS31FL3745_I2C_ADDRESS_3) | ||
| 109 | is31fl3745_init(IS31FL3745_I2C_ADDRESS_3, IS31FL3745_SYNC_3); | ||
| 110 | # if defined(IS31FL3745_I2C_ADDRESS_4) | ||
| 111 | is31fl3745_init(IS31FL3745_I2C_ADDRESS_4, IS31FL3745_SYNC_4); | ||
| 112 | # endif | ||
| 113 | # endif | ||
| 114 | #endif | ||
| 115 | 134 | ||
| 116 | for (int i = 0; i < IS31FL3745_LED_COUNT; i++) { | 135 | for (int i = 0; i < IS31FL3745_LED_COUNT; i++) { |
| 117 | is31fl3745_set_scaling_register(i, 0xFF, 0xFF, 0xFF); | 136 | is31fl3745_set_scaling_register(i, 0xFF, 0xFF, 0xFF); |
| 118 | } | 137 | } |
| 119 | 138 | ||
| 120 | is31fl3745_update_scaling_registers(IS31FL3745_I2C_ADDRESS_1, 0); | 139 | for (uint8_t i = 0; i < IS31FL3745_DRIVER_COUNT; i++) { |
| 121 | #if defined(IS31FL3745_I2C_ADDRESS_2) | 140 | is31fl3745_update_scaling_registers(i); |
| 122 | is31fl3745_update_scaling_registers(IS31FL3745_I2C_ADDRESS_2, 1); | 141 | } |
| 123 | # if defined(IS31FL3745_I2C_ADDRESS_3) | ||
| 124 | is31fl3745_update_scaling_registers(IS31FL3745_I2C_ADDRESS_3, 2); | ||
| 125 | # if defined(IS31FL3745_I2C_ADDRESS_4) | ||
| 126 | is31fl3745_update_scaling_registers(IS31FL3745_I2C_ADDRESS_4, 3); | ||
| 127 | # endif | ||
| 128 | # endif | ||
| 129 | #endif | ||
| 130 | } | 142 | } |
| 131 | 143 | ||
| 132 | void is31fl3745_init(uint8_t addr, uint8_t sync) { | 144 | void is31fl3745_init(uint8_t index) { |
| 133 | // In order to avoid the LEDs being driven with garbage data | 145 | // In order to avoid the LEDs being driven with garbage data |
| 134 | // in the LED driver's PWM registers, shutdown is enabled last. | 146 | // in the LED driver's PWM registers, shutdown is enabled last. |
| 135 | // Set up the mode and other settings, clear the PWM registers, | 147 | // Set up the mode and other settings, clear the PWM registers, |
| 136 | // then disable software shutdown. | 148 | // then disable software shutdown. |
| 137 | 149 | ||
| 138 | is31fl3745_select_page(addr, IS31FL3745_COMMAND_SCALING); | 150 | is31fl3745_select_page(index, IS31FL3745_COMMAND_SCALING); |
| 139 | 151 | ||
| 140 | // Turn off all LEDs. | 152 | // Turn off all LEDs. |
| 141 | for (uint8_t i = 0; i < IS31FL3745_SCALING_REGISTER_COUNT; i++) { | 153 | for (uint8_t i = 0; i < IS31FL3745_SCALING_REGISTER_COUNT; i++) { |
| 142 | is31fl3745_write_register(addr, i + 1, 0x00); | 154 | is31fl3745_write_register(index, i + 1, 0x00); |
| 143 | } | 155 | } |
| 144 | 156 | ||
| 145 | is31fl3745_select_page(addr, IS31FL3745_COMMAND_PWM); | 157 | is31fl3745_select_page(index, IS31FL3745_COMMAND_PWM); |
| 146 | 158 | ||
| 147 | for (uint8_t i = 0; i < IS31FL3745_PWM_REGISTER_COUNT; i++) { | 159 | for (uint8_t i = 0; i < IS31FL3745_PWM_REGISTER_COUNT; i++) { |
| 148 | is31fl3745_write_register(addr, i + 1, 0x00); | 160 | is31fl3745_write_register(index, i + 1, 0x00); |
| 149 | } | 161 | } |
| 150 | 162 | ||
| 151 | is31fl3745_select_page(addr, IS31FL3745_COMMAND_FUNCTION); | 163 | is31fl3745_select_page(index, IS31FL3745_COMMAND_FUNCTION); |
| 152 | 164 | ||
| 153 | is31fl3745_write_register(addr, IS31FL3745_FUNCTION_REG_PULLDOWNUP, (IS31FL3745_SW_PULLDOWN << 4) | IS31FL3745_CS_PULLUP); | 165 | uint8_t sync = driver_sync[index]; |
| 154 | is31fl3745_write_register(addr, IS31FL3745_FUNCTION_REG_GLOBAL_CURRENT, IS31FL3745_GLOBAL_CURRENT); | 166 | |
| 155 | is31fl3745_write_register(addr, IS31FL3745_FUNCTION_REG_SPREAD_SPECTRUM, (sync & 0b11) << 6); | 167 | is31fl3745_write_register(index, IS31FL3745_FUNCTION_REG_PULLDOWNUP, (IS31FL3745_SW_PULLDOWN << 4) | IS31FL3745_CS_PULLUP); |
| 156 | is31fl3745_write_register(addr, IS31FL3745_FUNCTION_REG_CONFIGURATION, IS31FL3745_CONFIGURATION); | 168 | is31fl3745_write_register(index, IS31FL3745_FUNCTION_REG_GLOBAL_CURRENT, IS31FL3745_GLOBAL_CURRENT); |
| 169 | is31fl3745_write_register(index, IS31FL3745_FUNCTION_REG_SPREAD_SPECTRUM, (sync & 0b11) << 6); | ||
| 170 | is31fl3745_write_register(index, IS31FL3745_FUNCTION_REG_CONFIGURATION, IS31FL3745_CONFIGURATION); | ||
| 157 | 171 | ||
| 158 | // Wait 10ms to ensure the device has woken up. | 172 | // Wait 10ms to ensure the device has woken up. |
| 159 | wait_ms(10); | 173 | wait_ms(10); |
| @@ -192,22 +206,22 @@ void is31fl3745_set_scaling_register(uint8_t index, uint8_t red, uint8_t green, | |||
| 192 | g_scaling_registers_update_required[led.driver] = true; | 206 | g_scaling_registers_update_required[led.driver] = true; |
| 193 | } | 207 | } |
| 194 | 208 | ||
| 195 | void is31fl3745_update_pwm_buffers(uint8_t addr, uint8_t index) { | 209 | void is31fl3745_update_pwm_buffers(uint8_t index) { |
| 196 | if (g_pwm_buffer_update_required[index]) { | 210 | if (g_pwm_buffer_update_required[index]) { |
| 197 | is31fl3745_select_page(addr, IS31FL3745_COMMAND_PWM); | 211 | is31fl3745_select_page(index, IS31FL3745_COMMAND_PWM); |
| 198 | 212 | ||
| 199 | is31fl3745_write_pwm_buffer(addr, index); | 213 | is31fl3745_write_pwm_buffer(index); |
| 200 | 214 | ||
| 201 | g_pwm_buffer_update_required[index] = false; | 215 | g_pwm_buffer_update_required[index] = false; |
| 202 | } | 216 | } |
| 203 | } | 217 | } |
| 204 | 218 | ||
| 205 | void is31fl3745_update_scaling_registers(uint8_t addr, uint8_t index) { | 219 | void is31fl3745_update_scaling_registers(uint8_t index) { |
| 206 | if (g_scaling_registers_update_required[index]) { | 220 | if (g_scaling_registers_update_required[index]) { |
| 207 | is31fl3745_select_page(addr, IS31FL3745_COMMAND_SCALING); | 221 | is31fl3745_select_page(index, IS31FL3745_COMMAND_SCALING); |
| 208 | 222 | ||
| 209 | for (uint8_t i = 0; i < IS31FL3745_SCALING_REGISTER_COUNT; i++) { | 223 | for (uint8_t i = 0; i < IS31FL3745_SCALING_REGISTER_COUNT; i++) { |
| 210 | is31fl3745_write_register(addr, i + 1, g_scaling_registers[index][i]); | 224 | is31fl3745_write_register(index, i + 1, g_scaling_registers[index][i]); |
| 211 | } | 225 | } |
| 212 | 226 | ||
| 213 | g_scaling_registers_update_required[index] = false; | 227 | g_scaling_registers_update_required[index] = false; |
| @@ -215,14 +229,7 @@ void is31fl3745_update_scaling_registers(uint8_t addr, uint8_t index) { | |||
| 215 | } | 229 | } |
| 216 | 230 | ||
| 217 | void is31fl3745_flush(void) { | 231 | void is31fl3745_flush(void) { |
| 218 | is31fl3745_update_pwm_buffers(IS31FL3745_I2C_ADDRESS_1, 0); | 232 | for (uint8_t i = 0; i < IS31FL3745_DRIVER_COUNT; i++) { |
| 219 | #if defined(IS31FL3745_I2C_ADDRESS_2) | 233 | is31fl3745_update_pwm_buffers(i); |
| 220 | is31fl3745_update_pwm_buffers(IS31FL3745_I2C_ADDRESS_2, 1); | 234 | } |
| 221 | # if defined(IS31FL3745_I2C_ADDRESS_3) | ||
| 222 | is31fl3745_update_pwm_buffers(IS31FL3745_I2C_ADDRESS_3, 2); | ||
| 223 | # if defined(IS31FL3745_I2C_ADDRESS_4) | ||
| 224 | is31fl3745_update_pwm_buffers(IS31FL3745_I2C_ADDRESS_4, 3); | ||
| 225 | # endif | ||
| 226 | # endif | ||
| 227 | #endif | ||
| 228 | } | 235 | } |
diff --git a/drivers/led/issi/is31fl3745.h b/drivers/led/issi/is31fl3745.h index 3c67f7ecc7..264f4f9c74 100644 --- a/drivers/led/issi/is31fl3745.h +++ b/drivers/led/issi/is31fl3745.h | |||
| @@ -84,17 +84,17 @@ typedef struct is31fl3745_led_t { | |||
| 84 | extern const is31fl3745_led_t PROGMEM g_is31fl3745_leds[IS31FL3745_LED_COUNT]; | 84 | extern const is31fl3745_led_t PROGMEM g_is31fl3745_leds[IS31FL3745_LED_COUNT]; |
| 85 | 85 | ||
| 86 | void is31fl3745_init_drivers(void); | 86 | void is31fl3745_init_drivers(void); |
| 87 | void is31fl3745_init(uint8_t addr, uint8_t sync); | 87 | void is31fl3745_init(uint8_t index); |
| 88 | void is31fl3745_write_register(uint8_t addr, uint8_t reg, uint8_t data); | 88 | void is31fl3745_write_register(uint8_t index, uint8_t reg, uint8_t data); |
| 89 | void is31fl3745_select_page(uint8_t addr, uint8_t page); | 89 | void is31fl3745_select_page(uint8_t index, uint8_t page); |
| 90 | 90 | ||
| 91 | void is31fl3745_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); | 91 | void is31fl3745_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); |
| 92 | void is31fl3745_set_color_all(uint8_t red, uint8_t green, uint8_t blue); | 92 | void is31fl3745_set_color_all(uint8_t red, uint8_t green, uint8_t blue); |
| 93 | 93 | ||
| 94 | void is31fl3745_set_scaling_register(uint8_t index, uint8_t red, uint8_t green, uint8_t blue); | 94 | void is31fl3745_set_scaling_register(uint8_t index, uint8_t red, uint8_t green, uint8_t blue); |
| 95 | 95 | ||
| 96 | void is31fl3745_update_pwm_buffers(uint8_t addr, uint8_t index); | 96 | void is31fl3745_update_pwm_buffers(uint8_t index); |
| 97 | void is31fl3745_update_scaling_registers(uint8_t addr, uint8_t index); | 97 | void is31fl3745_update_scaling_registers(uint8_t index); |
| 98 | 98 | ||
| 99 | void is31fl3745_flush(void); | 99 | void is31fl3745_flush(void); |
| 100 | 100 | ||
diff --git a/drivers/led/issi/is31fl3746a-mono.c b/drivers/led/issi/is31fl3746a-mono.c index c21269b3a3..900482e75c 100644 --- a/drivers/led/issi/is31fl3746a-mono.c +++ b/drivers/led/issi/is31fl3746a-mono.c | |||
| @@ -53,28 +53,41 @@ | |||
| 53 | # define IS31FL3746A_GLOBAL_CURRENT 0xFF | 53 | # define IS31FL3746A_GLOBAL_CURRENT 0xFF |
| 54 | #endif | 54 | #endif |
| 55 | 55 | ||
| 56 | const uint8_t i2c_addresses[IS31FL3746A_DRIVER_COUNT] = { | ||
| 57 | IS31FL3746A_I2C_ADDRESS_1, | ||
| 58 | #ifdef IS31FL3746A_I2C_ADDRESS_2 | ||
| 59 | IS31FL3746A_I2C_ADDRESS_2, | ||
| 60 | # ifdef IS31FL3746A_I2C_ADDRESS_3 | ||
| 61 | IS31FL3746A_I2C_ADDRESS_3, | ||
| 62 | # ifdef IS31FL3746A_I2C_ADDRESS_4 | ||
| 63 | IS31FL3746A_I2C_ADDRESS_4, | ||
| 64 | # endif | ||
| 65 | # endif | ||
| 66 | #endif | ||
| 67 | }; | ||
| 68 | |||
| 56 | uint8_t g_pwm_buffer[IS31FL3746A_DRIVER_COUNT][IS31FL3746A_PWM_REGISTER_COUNT]; | 69 | uint8_t g_pwm_buffer[IS31FL3746A_DRIVER_COUNT][IS31FL3746A_PWM_REGISTER_COUNT]; |
| 57 | bool g_pwm_buffer_update_required[IS31FL3746A_DRIVER_COUNT] = {false}; | 70 | bool g_pwm_buffer_update_required[IS31FL3746A_DRIVER_COUNT] = {false}; |
| 58 | bool g_scaling_registers_update_required[IS31FL3746A_DRIVER_COUNT] = {false}; | 71 | bool g_scaling_registers_update_required[IS31FL3746A_DRIVER_COUNT] = {false}; |
| 59 | 72 | ||
| 60 | uint8_t g_scaling_registers[IS31FL3746A_DRIVER_COUNT][IS31FL3746A_SCALING_REGISTER_COUNT]; | 73 | uint8_t g_scaling_registers[IS31FL3746A_DRIVER_COUNT][IS31FL3746A_SCALING_REGISTER_COUNT]; |
| 61 | 74 | ||
| 62 | void is31fl3746a_write_register(uint8_t addr, uint8_t reg, uint8_t data) { | 75 | void is31fl3746a_write_register(uint8_t index, uint8_t reg, uint8_t data) { |
| 63 | #if IS31FL3746A_I2C_PERSISTENCE > 0 | 76 | #if IS31FL3746A_I2C_PERSISTENCE > 0 |
| 64 | for (uint8_t i = 0; i < IS31FL3746A_I2C_PERSISTENCE; i++) { | 77 | for (uint8_t i = 0; i < IS31FL3746A_I2C_PERSISTENCE; i++) { |
| 65 | if (i2c_write_register(addr << 1, reg, &data, 1, IS31FL3746A_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; | 78 | if (i2c_write_register(i2c_addresses[index] << 1, reg, &data, 1, IS31FL3746A_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; |
| 66 | } | 79 | } |
| 67 | #else | 80 | #else |
| 68 | i2c_write_register(addr << 1, reg, &data, 1, IS31FL3746A_I2C_TIMEOUT); | 81 | i2c_write_register(i2c_addresses[index] << 1, reg, &data, 1, IS31FL3746A_I2C_TIMEOUT); |
| 69 | #endif | 82 | #endif |
| 70 | } | 83 | } |
| 71 | 84 | ||
| 72 | void is31fl3746a_select_page(uint8_t addr, uint8_t page) { | 85 | void is31fl3746a_select_page(uint8_t index, uint8_t page) { |
| 73 | is31fl3746a_write_register(addr, IS31FL3746A_REG_COMMAND_WRITE_LOCK, IS31FL3746A_COMMAND_WRITE_LOCK_MAGIC); | 86 | is31fl3746a_write_register(index, IS31FL3746A_REG_COMMAND_WRITE_LOCK, IS31FL3746A_COMMAND_WRITE_LOCK_MAGIC); |
| 74 | is31fl3746a_write_register(addr, IS31FL3746A_REG_COMMAND, page); | 87 | is31fl3746a_write_register(index, IS31FL3746A_REG_COMMAND, page); |
| 75 | } | 88 | } |
| 76 | 89 | ||
| 77 | void is31fl3746a_write_pwm_buffer(uint8_t addr, uint8_t index) { | 90 | void is31fl3746a_write_pwm_buffer(uint8_t index) { |
| 78 | // Assumes page 0 is already selected. | 91 | // Assumes page 0 is already selected. |
| 79 | // Transmit PWM registers in 4 transfers of 18 bytes. | 92 | // Transmit PWM registers in 4 transfers of 18 bytes. |
| 80 | 93 | ||
| @@ -82,10 +95,10 @@ void is31fl3746a_write_pwm_buffer(uint8_t addr, uint8_t index) { | |||
| 82 | for (uint8_t i = 0; i < IS31FL3746A_PWM_REGISTER_COUNT; i += 18) { | 95 | for (uint8_t i = 0; i < IS31FL3746A_PWM_REGISTER_COUNT; i += 18) { |
| 83 | #if IS31FL3746A_I2C_PERSISTENCE > 0 | 96 | #if IS31FL3746A_I2C_PERSISTENCE > 0 |
| 84 | for (uint8_t j = 0; j < IS31FL3746A_I2C_PERSISTENCE; j++) { | 97 | for (uint8_t j = 0; j < IS31FL3746A_I2C_PERSISTENCE; j++) { |
| 85 | if (i2c_write_register(addr << 1, i + 1, g_pwm_buffer[index] + i, 18, IS31FL3746A_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; | 98 | if (i2c_write_register(i2c_addresses[index] << 1, i + 1, g_pwm_buffer[index] + i, 18, IS31FL3746A_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; |
| 86 | } | 99 | } |
| 87 | #else | 100 | #else |
| 88 | i2c_write_register(addr << 1, i + 1, g_pwm_buffer[index] + i, 18, IS31FL3746A_I2C_TIMEOUT); | 101 | i2c_write_register(i2c_addresses[index] << 1, i + 1, g_pwm_buffer[index] + i, 18, IS31FL3746A_I2C_TIMEOUT); |
| 89 | #endif | 102 | #endif |
| 90 | } | 103 | } |
| 91 | } | 104 | } |
| @@ -93,59 +106,45 @@ void is31fl3746a_write_pwm_buffer(uint8_t addr, uint8_t index) { | |||
| 93 | void is31fl3746a_init_drivers(void) { | 106 | void is31fl3746a_init_drivers(void) { |
| 94 | i2c_init(); | 107 | i2c_init(); |
| 95 | 108 | ||
| 96 | is31fl3746a_init(IS31FL3746A_I2C_ADDRESS_1); | 109 | for (uint8_t i = 0; i < IS31FL3746A_DRIVER_COUNT; i++) { |
| 97 | #if defined(IS31FL3746A_I2C_ADDRESS_2) | 110 | is31fl3746a_init(i); |
| 98 | is31fl3746a_init(IS31FL3746A_I2C_ADDRESS_2); | 111 | } |
| 99 | # if defined(IS31FL3746A_I2C_ADDRESS_3) | ||
| 100 | is31fl3746a_init(IS31FL3746A_I2C_ADDRESS_3); | ||
| 101 | # if defined(IS31FL3746A_I2C_ADDRESS_4) | ||
| 102 | is31fl3746a_init(IS31FL3746A_I2C_ADDRESS_4); | ||
| 103 | # endif | ||
| 104 | # endif | ||
| 105 | #endif | ||
| 106 | 112 | ||
| 107 | for (int i = 0; i < IS31FL3746A_LED_COUNT; i++) { | 113 | for (int i = 0; i < IS31FL3746A_LED_COUNT; i++) { |
| 108 | is31fl3746a_set_scaling_register(i, 0xFF); | 114 | is31fl3746a_set_scaling_register(i, 0xFF); |
| 109 | } | 115 | } |
| 110 | 116 | ||
| 111 | is31fl3746a_update_scaling_registers(IS31FL3746A_I2C_ADDRESS_1, 0); | 117 | for (uint8_t i = 0; i < IS31FL3746A_DRIVER_COUNT; i++) { |
| 112 | #if defined(IS31FL3746A_I2C_ADDRESS_2) | 118 | is31fl3746a_update_scaling_registers(i); |
| 113 | is31fl3746a_update_scaling_registers(IS31FL3746A_I2C_ADDRESS_2, 1); | 119 | } |
| 114 | # if defined(IS31FL3746A_I2C_ADDRESS_3) | ||
| 115 | is31fl3746a_update_scaling_registers(IS31FL3746A_I2C_ADDRESS_3, 2); | ||
| 116 | # if defined(IS31FL3746A_I2C_ADDRESS_4) | ||
| 117 | is31fl3746a_update_scaling_registers(IS31FL3746A_I2C_ADDRESS_4, 3); | ||
| 118 | # endif | ||
| 119 | # endif | ||
| 120 | #endif | ||
| 121 | } | 120 | } |
| 122 | 121 | ||
| 123 | void is31fl3746a_init(uint8_t addr) { | 122 | void is31fl3746a_init(uint8_t index) { |
| 124 | // In order to avoid the LEDs being driven with garbage data | 123 | // In order to avoid the LEDs being driven with garbage data |
| 125 | // in the LED driver's PWM registers, shutdown is enabled last. | 124 | // in the LED driver's PWM registers, shutdown is enabled last. |
| 126 | // Set up the mode and other settings, clear the PWM registers, | 125 | // Set up the mode and other settings, clear the PWM registers, |
| 127 | // then disable software shutdown. | 126 | // then disable software shutdown. |
| 128 | 127 | ||
| 129 | is31fl3746a_select_page(addr, IS31FL3746A_COMMAND_SCALING); | 128 | is31fl3746a_select_page(index, IS31FL3746A_COMMAND_SCALING); |
| 130 | 129 | ||
| 131 | // Turn off all LEDs. | 130 | // Turn off all LEDs. |
| 132 | for (uint8_t i = 0; i < IS31FL3746A_SCALING_REGISTER_COUNT; i++) { | 131 | for (uint8_t i = 0; i < IS31FL3746A_SCALING_REGISTER_COUNT; i++) { |
| 133 | is31fl3746a_write_register(addr, i + 1, 0x00); | 132 | is31fl3746a_write_register(index, i + 1, 0x00); |
| 134 | } | 133 | } |
| 135 | 134 | ||
| 136 | is31fl3746a_select_page(addr, IS31FL3746A_COMMAND_PWM); | 135 | is31fl3746a_select_page(index, IS31FL3746A_COMMAND_PWM); |
| 137 | 136 | ||
| 138 | for (uint8_t i = 0; i < IS31FL3746A_PWM_REGISTER_COUNT; i++) { | 137 | for (uint8_t i = 0; i < IS31FL3746A_PWM_REGISTER_COUNT; i++) { |
| 139 | is31fl3746a_write_register(addr, i + 1, 0x00); | 138 | is31fl3746a_write_register(index, i + 1, 0x00); |
| 140 | } | 139 | } |
| 141 | 140 | ||
| 142 | is31fl3746a_select_page(addr, IS31FL3746A_COMMAND_FUNCTION); | 141 | is31fl3746a_select_page(index, IS31FL3746A_COMMAND_FUNCTION); |
| 143 | 142 | ||
| 144 | is31fl3746a_write_register(addr, IS31FL3746A_FUNCTION_REG_PULLDOWNUP, (IS31FL3746A_SW_PULLDOWN << 4) | IS31FL3746A_CS_PULLUP); | 143 | is31fl3746a_write_register(index, IS31FL3746A_FUNCTION_REG_PULLDOWNUP, (IS31FL3746A_SW_PULLDOWN << 4) | IS31FL3746A_CS_PULLUP); |
| 145 | is31fl3746a_write_register(addr, IS31FL3746A_FUNCTION_REG_GLOBAL_CURRENT, IS31FL3746A_GLOBAL_CURRENT); | 144 | is31fl3746a_write_register(index, IS31FL3746A_FUNCTION_REG_GLOBAL_CURRENT, IS31FL3746A_GLOBAL_CURRENT); |
| 146 | is31fl3746a_write_register(addr, IS31FL3746A_FUNCTION_REG_PWM_ENABLE, 0x01); | 145 | is31fl3746a_write_register(index, IS31FL3746A_FUNCTION_REG_PWM_ENABLE, 0x01); |
| 147 | is31fl3746a_write_register(addr, IS31FL3746A_FUNCTION_REG_PWM_FREQUENCY, IS31FL3746A_PWM_FREQUENCY); | 146 | is31fl3746a_write_register(index, IS31FL3746A_FUNCTION_REG_PWM_FREQUENCY, IS31FL3746A_PWM_FREQUENCY); |
| 148 | is31fl3746a_write_register(addr, IS31FL3746A_FUNCTION_REG_CONFIGURATION, IS31FL3746A_CONFIGURATION); | 147 | is31fl3746a_write_register(index, IS31FL3746A_FUNCTION_REG_CONFIGURATION, IS31FL3746A_CONFIGURATION); |
| 149 | 148 | ||
| 150 | // Wait 10ms to ensure the device has woken up. | 149 | // Wait 10ms to ensure the device has woken up. |
| 151 | wait_ms(10); | 150 | wait_ms(10); |
| @@ -180,22 +179,22 @@ void is31fl3746a_set_scaling_register(uint8_t index, uint8_t value) { | |||
| 180 | g_scaling_registers_update_required[led.driver] = true; | 179 | g_scaling_registers_update_required[led.driver] = true; |
| 181 | } | 180 | } |
| 182 | 181 | ||
| 183 | void is31fl3746a_update_pwm_buffers(uint8_t addr, uint8_t index) { | 182 | void is31fl3746a_update_pwm_buffers(uint8_t index) { |
| 184 | if (g_pwm_buffer_update_required[index]) { | 183 | if (g_pwm_buffer_update_required[index]) { |
| 185 | is31fl3746a_select_page(addr, IS31FL3746A_COMMAND_PWM); | 184 | is31fl3746a_select_page(index, IS31FL3746A_COMMAND_PWM); |
| 186 | 185 | ||
| 187 | is31fl3746a_write_pwm_buffer(addr, index); | 186 | is31fl3746a_write_pwm_buffer(index); |
| 188 | 187 | ||
| 189 | g_pwm_buffer_update_required[index] = false; | 188 | g_pwm_buffer_update_required[index] = false; |
| 190 | } | 189 | } |
| 191 | } | 190 | } |
| 192 | 191 | ||
| 193 | void is31fl3746a_update_scaling_registers(uint8_t addr, uint8_t index) { | 192 | void is31fl3746a_update_scaling_registers(uint8_t index) { |
| 194 | if (g_scaling_registers_update_required[index]) { | 193 | if (g_scaling_registers_update_required[index]) { |
| 195 | is31fl3746a_select_page(addr, IS31FL3746A_COMMAND_SCALING); | 194 | is31fl3746a_select_page(index, IS31FL3746A_COMMAND_SCALING); |
| 196 | 195 | ||
| 197 | for (uint8_t i = 0; i < IS31FL3746A_SCALING_REGISTER_COUNT; i++) { | 196 | for (uint8_t i = 0; i < IS31FL3746A_SCALING_REGISTER_COUNT; i++) { |
| 198 | is31fl3746a_write_register(addr, i + 1, g_scaling_registers[index][i]); | 197 | is31fl3746a_write_register(index, i + 1, g_scaling_registers[index][i]); |
| 199 | } | 198 | } |
| 200 | 199 | ||
| 201 | g_scaling_registers_update_required[index] = false; | 200 | g_scaling_registers_update_required[index] = false; |
| @@ -203,14 +202,7 @@ void is31fl3746a_update_scaling_registers(uint8_t addr, uint8_t index) { | |||
| 203 | } | 202 | } |
| 204 | 203 | ||
| 205 | void is31fl3746a_flush(void) { | 204 | void is31fl3746a_flush(void) { |
| 206 | is31fl3746a_update_pwm_buffers(IS31FL3746A_I2C_ADDRESS_1, 0); | 205 | for (uint8_t i = 0; i < IS31FL3746A_DRIVER_COUNT; i++) { |
| 207 | #if defined(IS31FL3746A_I2C_ADDRESS_2) | 206 | is31fl3746a_update_pwm_buffers(i); |
| 208 | is31fl3746a_update_pwm_buffers(IS31FL3746A_I2C_ADDRESS_2, 1); | 207 | } |
| 209 | # if defined(IS31FL3746A_I2C_ADDRESS_3) | ||
| 210 | is31fl3746a_update_pwm_buffers(IS31FL3746A_I2C_ADDRESS_3, 2); | ||
| 211 | # if defined(IS31FL3746A_I2C_ADDRESS_4) | ||
| 212 | is31fl3746a_update_pwm_buffers(IS31FL3746A_I2C_ADDRESS_4, 3); | ||
| 213 | # endif | ||
| 214 | # endif | ||
| 215 | #endif | ||
| 216 | } | 208 | } |
diff --git a/drivers/led/issi/is31fl3746a-mono.h b/drivers/led/issi/is31fl3746a-mono.h index 002a91f175..1fa1a1e520 100644 --- a/drivers/led/issi/is31fl3746a-mono.h +++ b/drivers/led/issi/is31fl3746a-mono.h | |||
| @@ -84,17 +84,17 @@ typedef struct is31fl3746a_led_t { | |||
| 84 | extern const is31fl3746a_led_t PROGMEM g_is31fl3746a_leds[IS31FL3746A_LED_COUNT]; | 84 | extern const is31fl3746a_led_t PROGMEM g_is31fl3746a_leds[IS31FL3746A_LED_COUNT]; |
| 85 | 85 | ||
| 86 | void is31fl3746a_init_drivers(void); | 86 | void is31fl3746a_init_drivers(void); |
| 87 | void is31fl3746a_init(uint8_t addr); | 87 | void is31fl3746a_init(uint8_t index); |
| 88 | void is31fl3746a_write_register(uint8_t addr, uint8_t reg, uint8_t data); | 88 | void is31fl3746a_write_register(uint8_t index, uint8_t reg, uint8_t data); |
| 89 | void is31fl3746a_select_page(uint8_t addr, uint8_t page); | 89 | void is31fl3746a_select_page(uint8_t index, uint8_t page); |
| 90 | 90 | ||
| 91 | void is31fl3746a_set_value(int index, uint8_t value); | 91 | void is31fl3746a_set_value(int index, uint8_t value); |
| 92 | void is31fl3746a_set_value_all(uint8_t value); | 92 | void is31fl3746a_set_value_all(uint8_t value); |
| 93 | 93 | ||
| 94 | void is31fl3746a_set_scaling_register(uint8_t index, uint8_t value); | 94 | void is31fl3746a_set_scaling_register(uint8_t index, uint8_t value); |
| 95 | 95 | ||
| 96 | void is31fl3746a_update_pwm_buffers(uint8_t addr, uint8_t index); | 96 | void is31fl3746a_update_pwm_buffers(uint8_t index); |
| 97 | void is31fl3746a_update_scaling_registers(uint8_t addr, uint8_t index); | 97 | void is31fl3746a_update_scaling_registers(uint8_t index); |
| 98 | 98 | ||
| 99 | void is31fl3746a_flush(void); | 99 | void is31fl3746a_flush(void); |
| 100 | 100 | ||
diff --git a/drivers/led/issi/is31fl3746a.c b/drivers/led/issi/is31fl3746a.c index d167cdd90b..b4de9add6f 100644 --- a/drivers/led/issi/is31fl3746a.c +++ b/drivers/led/issi/is31fl3746a.c | |||
| @@ -53,28 +53,41 @@ | |||
| 53 | # define IS31FL3746A_GLOBAL_CURRENT 0xFF | 53 | # define IS31FL3746A_GLOBAL_CURRENT 0xFF |
| 54 | #endif | 54 | #endif |
| 55 | 55 | ||
| 56 | const uint8_t i2c_addresses[IS31FL3746A_DRIVER_COUNT] = { | ||
| 57 | IS31FL3746A_I2C_ADDRESS_1, | ||
| 58 | #ifdef IS31FL3746A_I2C_ADDRESS_2 | ||
| 59 | IS31FL3746A_I2C_ADDRESS_2, | ||
| 60 | # ifdef IS31FL3746A_I2C_ADDRESS_3 | ||
| 61 | IS31FL3746A_I2C_ADDRESS_3, | ||
| 62 | # ifdef IS31FL3746A_I2C_ADDRESS_4 | ||
| 63 | IS31FL3746A_I2C_ADDRESS_4, | ||
| 64 | # endif | ||
| 65 | # endif | ||
| 66 | #endif | ||
| 67 | }; | ||
| 68 | |||
| 56 | uint8_t g_pwm_buffer[IS31FL3746A_DRIVER_COUNT][IS31FL3746A_PWM_REGISTER_COUNT]; | 69 | uint8_t g_pwm_buffer[IS31FL3746A_DRIVER_COUNT][IS31FL3746A_PWM_REGISTER_COUNT]; |
| 57 | bool g_pwm_buffer_update_required[IS31FL3746A_DRIVER_COUNT] = {false}; | 70 | bool g_pwm_buffer_update_required[IS31FL3746A_DRIVER_COUNT] = {false}; |
| 58 | bool g_scaling_registers_update_required[IS31FL3746A_DRIVER_COUNT] = {false}; | 71 | bool g_scaling_registers_update_required[IS31FL3746A_DRIVER_COUNT] = {false}; |
| 59 | 72 | ||
| 60 | uint8_t g_scaling_registers[IS31FL3746A_DRIVER_COUNT][IS31FL3746A_SCALING_REGISTER_COUNT]; | 73 | uint8_t g_scaling_registers[IS31FL3746A_DRIVER_COUNT][IS31FL3746A_SCALING_REGISTER_COUNT]; |
| 61 | 74 | ||
| 62 | void is31fl3746a_write_register(uint8_t addr, uint8_t reg, uint8_t data) { | 75 | void is31fl3746a_write_register(uint8_t index, uint8_t reg, uint8_t data) { |
| 63 | #if IS31FL3746A_I2C_PERSISTENCE > 0 | 76 | #if IS31FL3746A_I2C_PERSISTENCE > 0 |
| 64 | for (uint8_t i = 0; i < IS31FL3746A_I2C_PERSISTENCE; i++) { | 77 | for (uint8_t i = 0; i < IS31FL3746A_I2C_PERSISTENCE; i++) { |
| 65 | if (i2c_write_register(addr << 1, reg, &data, 1, IS31FL3746A_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; | 78 | if (i2c_write_register(i2c_addresses[index] << 1, reg, &data, 1, IS31FL3746A_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; |
| 66 | } | 79 | } |
| 67 | #else | 80 | #else |
| 68 | i2c_write_register(addr << 1, reg, &data, 1, IS31FL3746A_I2C_TIMEOUT); | 81 | i2c_write_register(i2c_addresses[index] << 1, reg, &data, 1, IS31FL3746A_I2C_TIMEOUT); |
| 69 | #endif | 82 | #endif |
| 70 | } | 83 | } |
| 71 | 84 | ||
| 72 | void is31fl3746a_select_page(uint8_t addr, uint8_t page) { | 85 | void is31fl3746a_select_page(uint8_t index, uint8_t page) { |
| 73 | is31fl3746a_write_register(addr, IS31FL3746A_REG_COMMAND_WRITE_LOCK, IS31FL3746A_COMMAND_WRITE_LOCK_MAGIC); | 86 | is31fl3746a_write_register(index, IS31FL3746A_REG_COMMAND_WRITE_LOCK, IS31FL3746A_COMMAND_WRITE_LOCK_MAGIC); |
| 74 | is31fl3746a_write_register(addr, IS31FL3746A_REG_COMMAND, page); | 87 | is31fl3746a_write_register(index, IS31FL3746A_REG_COMMAND, page); |
| 75 | } | 88 | } |
| 76 | 89 | ||
| 77 | void is31fl3746a_write_pwm_buffer(uint8_t addr, uint8_t index) { | 90 | void is31fl3746a_write_pwm_buffer(uint8_t index) { |
| 78 | // Assumes page 0 is already selected. | 91 | // Assumes page 0 is already selected. |
| 79 | // Transmit PWM registers in 4 transfers of 18 bytes. | 92 | // Transmit PWM registers in 4 transfers of 18 bytes. |
| 80 | 93 | ||
| @@ -82,10 +95,10 @@ void is31fl3746a_write_pwm_buffer(uint8_t addr, uint8_t index) { | |||
| 82 | for (uint8_t i = 0; i < IS31FL3746A_PWM_REGISTER_COUNT; i += 18) { | 95 | for (uint8_t i = 0; i < IS31FL3746A_PWM_REGISTER_COUNT; i += 18) { |
| 83 | #if IS31FL3746A_I2C_PERSISTENCE > 0 | 96 | #if IS31FL3746A_I2C_PERSISTENCE > 0 |
| 84 | for (uint8_t j = 0; j < IS31FL3746A_I2C_PERSISTENCE; j++) { | 97 | for (uint8_t j = 0; j < IS31FL3746A_I2C_PERSISTENCE; j++) { |
| 85 | if (i2c_write_register(addr << 1, i + 1, g_pwm_buffer[index] + i, 18, IS31FL3746A_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; | 98 | if (i2c_write_register(i2c_addresses[index] << 1, i + 1, g_pwm_buffer[index] + i, 18, IS31FL3746A_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; |
| 86 | } | 99 | } |
| 87 | #else | 100 | #else |
| 88 | i2c_write_register(addr << 1, i + 1, g_pwm_buffer[index] + i, 18, IS31FL3746A_I2C_TIMEOUT); | 101 | i2c_write_register(i2c_addresses[index] << 1, i + 1, g_pwm_buffer[index] + i, 18, IS31FL3746A_I2C_TIMEOUT); |
| 89 | #endif | 102 | #endif |
| 90 | } | 103 | } |
| 91 | } | 104 | } |
| @@ -93,59 +106,45 @@ void is31fl3746a_write_pwm_buffer(uint8_t addr, uint8_t index) { | |||
| 93 | void is31fl3746a_init_drivers(void) { | 106 | void is31fl3746a_init_drivers(void) { |
| 94 | i2c_init(); | 107 | i2c_init(); |
| 95 | 108 | ||
| 96 | is31fl3746a_init(IS31FL3746A_I2C_ADDRESS_1); | 109 | for (uint8_t i = 0; i < IS31FL3746A_DRIVER_COUNT; i++) { |
| 97 | #if defined(IS31FL3746A_I2C_ADDRESS_2) | 110 | is31fl3746a_init(i); |
| 98 | is31fl3746a_init(IS31FL3746A_I2C_ADDRESS_2); | 111 | } |
| 99 | # if defined(IS31FL3746A_I2C_ADDRESS_3) | ||
| 100 | is31fl3746a_init(IS31FL3746A_I2C_ADDRESS_3); | ||
| 101 | # if defined(IS31FL3746A_I2C_ADDRESS_4) | ||
| 102 | is31fl3746a_init(IS31FL3746A_I2C_ADDRESS_4); | ||
| 103 | # endif | ||
| 104 | # endif | ||
| 105 | #endif | ||
| 106 | 112 | ||
| 107 | for (int i = 0; i < IS31FL3746A_LED_COUNT; i++) { | 113 | for (int i = 0; i < IS31FL3746A_LED_COUNT; i++) { |
| 108 | is31fl3746a_set_scaling_register(i, 0xFF, 0xFF, 0xFF); | 114 | is31fl3746a_set_scaling_register(i, 0xFF, 0xFF, 0xFF); |
| 109 | } | 115 | } |
| 110 | 116 | ||
| 111 | is31fl3746a_update_scaling_registers(IS31FL3746A_I2C_ADDRESS_1, 0); | 117 | for (uint8_t i = 0; i < IS31FL3746A_DRIVER_COUNT; i++) { |
| 112 | #if defined(IS31FL3746A_I2C_ADDRESS_2) | 118 | is31fl3746a_update_scaling_registers(i); |
| 113 | is31fl3746a_update_scaling_registers(IS31FL3746A_I2C_ADDRESS_2, 1); | 119 | } |
| 114 | # if defined(IS31FL3746A_I2C_ADDRESS_3) | ||
| 115 | is31fl3746a_update_scaling_registers(IS31FL3746A_I2C_ADDRESS_3, 2); | ||
| 116 | # if defined(IS31FL3746A_I2C_ADDRESS_4) | ||
| 117 | is31fl3746a_update_scaling_registers(IS31FL3746A_I2C_ADDRESS_4, 3); | ||
| 118 | # endif | ||
| 119 | # endif | ||
| 120 | #endif | ||
| 121 | } | 120 | } |
| 122 | 121 | ||
| 123 | void is31fl3746a_init(uint8_t addr) { | 122 | void is31fl3746a_init(uint8_t index) { |
| 124 | // In order to avoid the LEDs being driven with garbage data | 123 | // In order to avoid the LEDs being driven with garbage data |
| 125 | // in the LED driver's PWM registers, shutdown is enabled last. | 124 | // in the LED driver's PWM registers, shutdown is enabled last. |
| 126 | // Set up the mode and other settings, clear the PWM registers, | 125 | // Set up the mode and other settings, clear the PWM registers, |
| 127 | // then disable software shutdown. | 126 | // then disable software shutdown. |
| 128 | 127 | ||
| 129 | is31fl3746a_select_page(addr, IS31FL3746A_COMMAND_SCALING); | 128 | is31fl3746a_select_page(index, IS31FL3746A_COMMAND_SCALING); |
| 130 | 129 | ||
| 131 | // Turn off all LEDs. | 130 | // Turn off all LEDs. |
| 132 | for (uint8_t i = 0; i < IS31FL3746A_SCALING_REGISTER_COUNT; i++) { | 131 | for (uint8_t i = 0; i < IS31FL3746A_SCALING_REGISTER_COUNT; i++) { |
| 133 | is31fl3746a_write_register(addr, i + 1, 0x00); | 132 | is31fl3746a_write_register(index, i + 1, 0x00); |
| 134 | } | 133 | } |
| 135 | 134 | ||
| 136 | is31fl3746a_select_page(addr, IS31FL3746A_COMMAND_PWM); | 135 | is31fl3746a_select_page(index, IS31FL3746A_COMMAND_PWM); |
| 137 | 136 | ||
| 138 | for (uint8_t i = 0; i < IS31FL3746A_PWM_REGISTER_COUNT; i++) { | 137 | for (uint8_t i = 0; i < IS31FL3746A_PWM_REGISTER_COUNT; i++) { |
| 139 | is31fl3746a_write_register(addr, i + 1, 0x00); | 138 | is31fl3746a_write_register(index, i + 1, 0x00); |
| 140 | } | 139 | } |
| 141 | 140 | ||
| 142 | is31fl3746a_select_page(addr, IS31FL3746A_COMMAND_FUNCTION); | 141 | is31fl3746a_select_page(index, IS31FL3746A_COMMAND_FUNCTION); |
| 143 | 142 | ||
| 144 | is31fl3746a_write_register(addr, IS31FL3746A_FUNCTION_REG_PULLDOWNUP, (IS31FL3746A_SW_PULLDOWN << 4) | IS31FL3746A_CS_PULLUP); | 143 | is31fl3746a_write_register(index, IS31FL3746A_FUNCTION_REG_PULLDOWNUP, (IS31FL3746A_SW_PULLDOWN << 4) | IS31FL3746A_CS_PULLUP); |
| 145 | is31fl3746a_write_register(addr, IS31FL3746A_FUNCTION_REG_GLOBAL_CURRENT, IS31FL3746A_GLOBAL_CURRENT); | 144 | is31fl3746a_write_register(index, IS31FL3746A_FUNCTION_REG_GLOBAL_CURRENT, IS31FL3746A_GLOBAL_CURRENT); |
| 146 | is31fl3746a_write_register(addr, IS31FL3746A_FUNCTION_REG_PWM_ENABLE, 0x01); | 145 | is31fl3746a_write_register(index, IS31FL3746A_FUNCTION_REG_PWM_ENABLE, 0x01); |
| 147 | is31fl3746a_write_register(addr, IS31FL3746A_FUNCTION_REG_PWM_FREQUENCY, IS31FL3746A_PWM_FREQUENCY); | 146 | is31fl3746a_write_register(index, IS31FL3746A_FUNCTION_REG_PWM_FREQUENCY, IS31FL3746A_PWM_FREQUENCY); |
| 148 | is31fl3746a_write_register(addr, IS31FL3746A_FUNCTION_REG_CONFIGURATION, IS31FL3746A_CONFIGURATION); | 147 | is31fl3746a_write_register(index, IS31FL3746A_FUNCTION_REG_CONFIGURATION, IS31FL3746A_CONFIGURATION); |
| 149 | 148 | ||
| 150 | // Wait 10ms to ensure the device has woken up. | 149 | // Wait 10ms to ensure the device has woken up. |
| 151 | wait_ms(10); | 150 | wait_ms(10); |
| @@ -184,22 +183,22 @@ void is31fl3746a_set_scaling_register(uint8_t index, uint8_t red, uint8_t green, | |||
| 184 | g_scaling_registers_update_required[led.driver] = true; | 183 | g_scaling_registers_update_required[led.driver] = true; |
| 185 | } | 184 | } |
| 186 | 185 | ||
| 187 | void is31fl3746a_update_pwm_buffers(uint8_t addr, uint8_t index) { | 186 | void is31fl3746a_update_pwm_buffers(uint8_t index) { |
| 188 | if (g_pwm_buffer_update_required[index]) { | 187 | if (g_pwm_buffer_update_required[index]) { |
| 189 | is31fl3746a_select_page(addr, IS31FL3746A_COMMAND_PWM); | 188 | is31fl3746a_select_page(index, IS31FL3746A_COMMAND_PWM); |
| 190 | 189 | ||
| 191 | is31fl3746a_write_pwm_buffer(addr, index); | 190 | is31fl3746a_write_pwm_buffer(index); |
| 192 | 191 | ||
| 193 | g_pwm_buffer_update_required[index] = false; | 192 | g_pwm_buffer_update_required[index] = false; |
| 194 | } | 193 | } |
| 195 | } | 194 | } |
| 196 | 195 | ||
| 197 | void is31fl3746a_update_scaling_registers(uint8_t addr, uint8_t index) { | 196 | void is31fl3746a_update_scaling_registers(uint8_t index) { |
| 198 | if (g_scaling_registers_update_required[index]) { | 197 | if (g_scaling_registers_update_required[index]) { |
| 199 | is31fl3746a_select_page(addr, IS31FL3746A_COMMAND_SCALING); | 198 | is31fl3746a_select_page(index, IS31FL3746A_COMMAND_SCALING); |
| 200 | 199 | ||
| 201 | for (uint8_t i = 0; i < IS31FL3746A_SCALING_REGISTER_COUNT; i++) { | 200 | for (uint8_t i = 0; i < IS31FL3746A_SCALING_REGISTER_COUNT; i++) { |
| 202 | is31fl3746a_write_register(addr, i + 1, g_scaling_registers[index][i]); | 201 | is31fl3746a_write_register(index, i + 1, g_scaling_registers[index][i]); |
| 203 | } | 202 | } |
| 204 | 203 | ||
| 205 | g_scaling_registers_update_required[index] = false; | 204 | g_scaling_registers_update_required[index] = false; |
| @@ -207,14 +206,7 @@ void is31fl3746a_update_scaling_registers(uint8_t addr, uint8_t index) { | |||
| 207 | } | 206 | } |
| 208 | 207 | ||
| 209 | void is31fl3746a_flush(void) { | 208 | void is31fl3746a_flush(void) { |
| 210 | is31fl3746a_update_pwm_buffers(IS31FL3746A_I2C_ADDRESS_1, 0); | 209 | for (uint8_t i = 0; i < IS31FL3746A_DRIVER_COUNT; i++) { |
| 211 | #if defined(IS31FL3746A_I2C_ADDRESS_2) | 210 | is31fl3746a_update_pwm_buffers(i); |
| 212 | is31fl3746a_update_pwm_buffers(IS31FL3746A_I2C_ADDRESS_2, 1); | 211 | } |
| 213 | # if defined(IS31FL3746A_I2C_ADDRESS_3) | ||
| 214 | is31fl3746a_update_pwm_buffers(IS31FL3746A_I2C_ADDRESS_3, 2); | ||
| 215 | # if defined(IS31FL3746A_I2C_ADDRESS_4) | ||
| 216 | is31fl3746a_update_pwm_buffers(IS31FL3746A_I2C_ADDRESS_4, 3); | ||
| 217 | # endif | ||
| 218 | # endif | ||
| 219 | #endif | ||
| 220 | } | 212 | } |
diff --git a/drivers/led/issi/is31fl3746a.h b/drivers/led/issi/is31fl3746a.h index 32647a37bd..e3ea2b7bb7 100644 --- a/drivers/led/issi/is31fl3746a.h +++ b/drivers/led/issi/is31fl3746a.h | |||
| @@ -86,17 +86,17 @@ typedef struct is31fl3746a_led_t { | |||
| 86 | extern const is31fl3746a_led_t PROGMEM g_is31fl3746a_leds[IS31FL3746A_LED_COUNT]; | 86 | extern const is31fl3746a_led_t PROGMEM g_is31fl3746a_leds[IS31FL3746A_LED_COUNT]; |
| 87 | 87 | ||
| 88 | void is31fl3746a_init_drivers(void); | 88 | void is31fl3746a_init_drivers(void); |
| 89 | void is31fl3746a_init(uint8_t addr); | 89 | void is31fl3746a_init(uint8_t index); |
| 90 | void is31fl3746a_write_register(uint8_t addr, uint8_t reg, uint8_t data); | 90 | void is31fl3746a_write_register(uint8_t index, uint8_t reg, uint8_t data); |
| 91 | void is31fl3746a_select_page(uint8_t addr, uint8_t page); | 91 | void is31fl3746a_select_page(uint8_t index, uint8_t page); |
| 92 | 92 | ||
| 93 | void is31fl3746a_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); | 93 | void is31fl3746a_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); |
| 94 | void is31fl3746a_set_color_all(uint8_t red, uint8_t green, uint8_t blue); | 94 | void is31fl3746a_set_color_all(uint8_t red, uint8_t green, uint8_t blue); |
| 95 | 95 | ||
| 96 | void is31fl3746a_set_scaling_register(uint8_t index, uint8_t red, uint8_t green, uint8_t blue); | 96 | void is31fl3746a_set_scaling_register(uint8_t index, uint8_t red, uint8_t green, uint8_t blue); |
| 97 | 97 | ||
| 98 | void is31fl3746a_update_pwm_buffers(uint8_t addr, uint8_t index); | 98 | void is31fl3746a_update_pwm_buffers(uint8_t index); |
| 99 | void is31fl3746a_update_scaling_registers(uint8_t addr, uint8_t index); | 99 | void is31fl3746a_update_scaling_registers(uint8_t index); |
| 100 | 100 | ||
| 101 | void is31fl3746a_flush(void); | 101 | void is31fl3746a_flush(void); |
| 102 | 102 | ||
diff --git a/drivers/led/snled27351-mono.c b/drivers/led/snled27351-mono.c index 854d21d3dc..8893e83537 100644 --- a/drivers/led/snled27351-mono.c +++ b/drivers/led/snled27351-mono.c | |||
| @@ -37,6 +37,19 @@ | |||
| 37 | { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } | 37 | { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } |
| 38 | #endif | 38 | #endif |
| 39 | 39 | ||
| 40 | const uint8_t i2c_addresses[SNLED27351_DRIVER_COUNT] = { | ||
| 41 | SNLED27351_I2C_ADDRESS_1, | ||
| 42 | #ifdef SNLED27351_I2C_ADDRESS_2 | ||
| 43 | SNLED27351_I2C_ADDRESS_2, | ||
| 44 | # ifdef SNLED27351_I2C_ADDRESS_3 | ||
| 45 | SNLED27351_I2C_ADDRESS_3, | ||
| 46 | # ifdef SNLED27351_I2C_ADDRESS_4 | ||
| 47 | SNLED27351_I2C_ADDRESS_4, | ||
| 48 | # endif | ||
| 49 | # endif | ||
| 50 | #endif | ||
| 51 | }; | ||
| 52 | |||
| 40 | // These buffers match the SNLED27351 PWM registers. | 53 | // These buffers match the SNLED27351 PWM registers. |
| 41 | // The control buffers match the PG0 LED On/Off registers. | 54 | // The control buffers match the PG0 LED On/Off registers. |
| 42 | // Storing them like this is optimal for I2C transfers to the registers. | 55 | // Storing them like this is optimal for I2C transfers to the registers. |
| @@ -49,21 +62,21 @@ bool g_pwm_buffer_update_required[SNLED27351_DRIVER_COUNT] = {false}; | |||
| 49 | uint8_t g_led_control_registers[SNLED27351_DRIVER_COUNT][SNLED27351_LED_CONTROL_REGISTER_COUNT] = {0}; | 62 | uint8_t g_led_control_registers[SNLED27351_DRIVER_COUNT][SNLED27351_LED_CONTROL_REGISTER_COUNT] = {0}; |
| 50 | bool g_led_control_registers_update_required[SNLED27351_DRIVER_COUNT] = {false}; | 63 | bool g_led_control_registers_update_required[SNLED27351_DRIVER_COUNT] = {false}; |
| 51 | 64 | ||
| 52 | void snled27351_write_register(uint8_t addr, uint8_t reg, uint8_t data) { | 65 | void snled27351_write_register(uint8_t index, uint8_t reg, uint8_t data) { |
| 53 | #if SNLED27351_I2C_PERSISTENCE > 0 | 66 | #if SNLED27351_I2C_PERSISTENCE > 0 |
| 54 | for (uint8_t i = 0; i < SNLED27351_I2C_PERSISTENCE; i++) { | 67 | for (uint8_t i = 0; i < SNLED27351_I2C_PERSISTENCE; i++) { |
| 55 | if (i2c_write_register(addr << 1, reg, &data, 1, SNLED27351_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; | 68 | if (i2c_write_register(i2c_addresses[index] << 1, reg, &data, 1, SNLED27351_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; |
| 56 | } | 69 | } |
| 57 | #else | 70 | #else |
| 58 | i2c_write_register(addr << 1, reg, &data, 1, SNLED27351_I2C_TIMEOUT); | 71 | i2c_write_register(i2c_addresses[index] << 1, reg, &data, 1, SNLED27351_I2C_TIMEOUT); |
| 59 | #endif | 72 | #endif |
| 60 | } | 73 | } |
| 61 | 74 | ||
| 62 | void snled27351_select_page(uint8_t addr, uint8_t page) { | 75 | void snled27351_select_page(uint8_t index, uint8_t page) { |
| 63 | snled27351_write_register(addr, SNLED27351_REG_COMMAND, page); | 76 | snled27351_write_register(index, SNLED27351_REG_COMMAND, page); |
| 64 | } | 77 | } |
| 65 | 78 | ||
| 66 | void snled27351_write_pwm_buffer(uint8_t addr, uint8_t index) { | 79 | void snled27351_write_pwm_buffer(uint8_t index) { |
| 67 | // Assumes PG1 is already selected. | 80 | // Assumes PG1 is already selected. |
| 68 | // Transmit PWM registers in 12 transfers of 16 bytes. | 81 | // Transmit PWM registers in 12 transfers of 16 bytes. |
| 69 | 82 | ||
| @@ -71,10 +84,10 @@ void snled27351_write_pwm_buffer(uint8_t addr, uint8_t index) { | |||
| 71 | for (uint8_t i = 0; i < SNLED27351_PWM_REGISTER_COUNT; i += 16) { | 84 | for (uint8_t i = 0; i < SNLED27351_PWM_REGISTER_COUNT; i += 16) { |
| 72 | #if SNLED27351_I2C_PERSISTENCE > 0 | 85 | #if SNLED27351_I2C_PERSISTENCE > 0 |
| 73 | for (uint8_t j = 0; j < SNLED27351_I2C_PERSISTENCE; j++) { | 86 | for (uint8_t j = 0; j < SNLED27351_I2C_PERSISTENCE; j++) { |
| 74 | if (i2c_write_register(addr << 1, i, g_pwm_buffer[index] + i, 16, SNLED27351_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; | 87 | if (i2c_write_register(i2c_addresses[index] << 1, i, g_pwm_buffer[index] + i, 16, SNLED27351_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; |
| 75 | } | 88 | } |
| 76 | #else | 89 | #else |
| 77 | i2c_write_register(addr << 1, i, g_pwm_buffer[index] + i, 16, SNLED27351_I2C_TIMEOUT); | 90 | i2c_write_register(i2c_addresses[index] << 1, i, g_pwm_buffer[index] + i, 16, SNLED27351_I2C_TIMEOUT); |
| 78 | #endif | 91 | #endif |
| 79 | } | 92 | } |
| 80 | } | 93 | } |
| @@ -82,78 +95,64 @@ void snled27351_write_pwm_buffer(uint8_t addr, uint8_t index) { | |||
| 82 | void snled27351_init_drivers(void) { | 95 | void snled27351_init_drivers(void) { |
| 83 | i2c_init(); | 96 | i2c_init(); |
| 84 | 97 | ||
| 85 | snled27351_init(SNLED27351_I2C_ADDRESS_1); | 98 | for (uint8_t i = 0; i < SNLED27351_DRIVER_COUNT; i++) { |
| 86 | #if defined(SNLED27351_I2C_ADDRESS_2) | 99 | snled27351_init(i); |
| 87 | snled27351_init(SNLED27351_I2C_ADDRESS_2); | 100 | } |
| 88 | # if defined(SNLED27351_I2C_ADDRESS_3) | ||
| 89 | snled27351_init(SNLED27351_I2C_ADDRESS_3); | ||
| 90 | # if defined(SNLED27351_I2C_ADDRESS_4) | ||
| 91 | snled27351_init(SNLED27351_I2C_ADDRESS_4); | ||
| 92 | # endif | ||
| 93 | # endif | ||
| 94 | #endif | ||
| 95 | 101 | ||
| 96 | for (int i = 0; i < SNLED27351_LED_COUNT; i++) { | 102 | for (int i = 0; i < SNLED27351_LED_COUNT; i++) { |
| 97 | snled27351_set_led_control_register(i, true); | 103 | snled27351_set_led_control_register(i, true); |
| 98 | } | 104 | } |
| 99 | 105 | ||
| 100 | snled27351_update_led_control_registers(SNLED27351_I2C_ADDRESS_1, 0); | 106 | for (uint8_t i = 0; i < SNLED27351_DRIVER_COUNT; i++) { |
| 101 | #if defined(SNLED27351_I2C_ADDRESS_2) | 107 | snled27351_update_led_control_registers(i); |
| 102 | snled27351_update_led_control_registers(SNLED27351_I2C_ADDRESS_2, 1); | 108 | } |
| 103 | # if defined(SNLED27351_I2C_ADDRESS_3) | ||
| 104 | snled27351_update_led_control_registers(SNLED27351_I2C_ADDRESS_3, 2); | ||
| 105 | # if defined(SNLED27351_I2C_ADDRESS_4) | ||
| 106 | snled27351_update_led_control_registers(SNLED27351_I2C_ADDRESS_4, 3); | ||
| 107 | # endif | ||
| 108 | # endif | ||
| 109 | #endif | ||
| 110 | } | 109 | } |
| 111 | 110 | ||
| 112 | void snled27351_init(uint8_t addr) { | 111 | void snled27351_init(uint8_t index) { |
| 113 | snled27351_select_page(addr, SNLED27351_COMMAND_FUNCTION); | 112 | snled27351_select_page(index, SNLED27351_COMMAND_FUNCTION); |
| 114 | 113 | ||
| 115 | // Setting LED driver to shutdown mode | 114 | // Setting LED driver to shutdown mode |
| 116 | snled27351_write_register(addr, SNLED27351_FUNCTION_REG_SOFTWARE_SHUTDOWN, SNLED27351_SOFTWARE_SHUTDOWN_SSD_SHUTDOWN); | 115 | snled27351_write_register(index, SNLED27351_FUNCTION_REG_SOFTWARE_SHUTDOWN, SNLED27351_SOFTWARE_SHUTDOWN_SSD_SHUTDOWN); |
| 117 | // Setting internal channel pulldown/pullup | 116 | // Setting internal channel pulldown/pullup |
| 118 | snled27351_write_register(addr, SNLED27351_FUNCTION_REG_PULLDOWNUP, SNLED27351_PULLDOWNUP_ALL_ENABLED); | 117 | snled27351_write_register(index, SNLED27351_FUNCTION_REG_PULLDOWNUP, SNLED27351_PULLDOWNUP_ALL_ENABLED); |
| 119 | // Select number of scan phase | 118 | // Select number of scan phase |
| 120 | snled27351_write_register(addr, SNLED27351_FUNCTION_REG_SCAN_PHASE, SNLED27351_PHASE_CHANNEL); | 119 | snled27351_write_register(index, SNLED27351_FUNCTION_REG_SCAN_PHASE, SNLED27351_PHASE_CHANNEL); |
| 121 | // Setting PWM Delay Phase | 120 | // Setting PWM Delay Phase |
| 122 | snled27351_write_register(addr, SNLED27351_FUNCTION_REG_SLEW_RATE_CONTROL_MODE_1, SNLED27351_SLEW_RATE_CONTROL_MODE_1_PDP_ENABLE); | 121 | snled27351_write_register(index, SNLED27351_FUNCTION_REG_SLEW_RATE_CONTROL_MODE_1, SNLED27351_SLEW_RATE_CONTROL_MODE_1_PDP_ENABLE); |
| 123 | // Setting Driving/Sinking Channel Slew Rate | 122 | // Setting Driving/Sinking Channel Slew Rate |
| 124 | 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); | 123 | snled27351_write_register(index, SNLED27351_FUNCTION_REG_SLEW_RATE_CONTROL_MODE_2, SNLED27351_SLEW_RATE_CONTROL_MODE_2_DSL_ENABLE | SNLED27351_SLEW_RATE_CONTROL_MODE_2_SSL_ENABLE); |
| 125 | // Setting Iref | 124 | // Setting Iref |
| 126 | snled27351_write_register(addr, SNLED27351_FUNCTION_REG_SOFTWARE_SLEEP, 0); | 125 | snled27351_write_register(index, SNLED27351_FUNCTION_REG_SOFTWARE_SLEEP, 0); |
| 127 | 126 | ||
| 128 | snled27351_select_page(addr, SNLED27351_COMMAND_LED_CONTROL); | 127 | snled27351_select_page(index, SNLED27351_COMMAND_LED_CONTROL); |
| 129 | 128 | ||
| 130 | for (int i = 0; i < SNLED27351_LED_CONTROL_ON_OFF_LENGTH; i++) { | 129 | for (int i = 0; i < SNLED27351_LED_CONTROL_ON_OFF_LENGTH; i++) { |
| 131 | snled27351_write_register(addr, i, 0x00); | 130 | snled27351_write_register(index, i, 0x00); |
| 132 | } | 131 | } |
| 133 | 132 | ||
| 134 | snled27351_select_page(addr, SNLED27351_COMMAND_PWM); | 133 | snled27351_select_page(index, SNLED27351_COMMAND_PWM); |
| 135 | 134 | ||
| 136 | for (int i = 0; i < SNLED27351_LED_CURRENT_TUNE_LENGTH; i++) { | 135 | for (int i = 0; i < SNLED27351_LED_CURRENT_TUNE_LENGTH; i++) { |
| 137 | snled27351_write_register(addr, i, 0x00); | 136 | snled27351_write_register(index, i, 0x00); |
| 138 | } | 137 | } |
| 139 | 138 | ||
| 140 | snled27351_select_page(addr, SNLED27351_COMMAND_CURRENT_TUNE); | 139 | snled27351_select_page(index, SNLED27351_COMMAND_CURRENT_TUNE); |
| 141 | 140 | ||
| 142 | uint8_t current_tune_reg_list[SNLED27351_LED_CURRENT_TUNE_LENGTH] = SNLED27351_CURRENT_TUNE; | 141 | uint8_t current_tune_reg_list[SNLED27351_LED_CURRENT_TUNE_LENGTH] = SNLED27351_CURRENT_TUNE; |
| 143 | for (int i = 0; i < SNLED27351_LED_CURRENT_TUNE_LENGTH; i++) { | 142 | for (int i = 0; i < SNLED27351_LED_CURRENT_TUNE_LENGTH; i++) { |
| 144 | snled27351_write_register(addr, i, current_tune_reg_list[i]); | 143 | snled27351_write_register(index, i, current_tune_reg_list[i]); |
| 145 | } | 144 | } |
| 146 | 145 | ||
| 147 | snled27351_select_page(addr, SNLED27351_COMMAND_LED_CONTROL); | 146 | snled27351_select_page(index, SNLED27351_COMMAND_LED_CONTROL); |
| 148 | 147 | ||
| 149 | for (int i = 0; i < SNLED27351_LED_CONTROL_ON_OFF_LENGTH; i++) { | 148 | for (int i = 0; i < SNLED27351_LED_CONTROL_ON_OFF_LENGTH; i++) { |
| 150 | snled27351_write_register(addr, i, 0xFF); | 149 | snled27351_write_register(index, i, 0xFF); |
| 151 | } | 150 | } |
| 152 | 151 | ||
| 153 | snled27351_select_page(addr, SNLED27351_COMMAND_FUNCTION); | 152 | snled27351_select_page(index, SNLED27351_COMMAND_FUNCTION); |
| 154 | 153 | ||
| 155 | // Setting LED driver to normal mode | 154 | // Setting LED driver to normal mode |
| 156 | snled27351_write_register(addr, SNLED27351_FUNCTION_REG_SOFTWARE_SHUTDOWN, SNLED27351_SOFTWARE_SHUTDOWN_SSD_NORMAL); | 155 | snled27351_write_register(index, SNLED27351_FUNCTION_REG_SOFTWARE_SHUTDOWN, SNLED27351_SOFTWARE_SHUTDOWN_SSD_NORMAL); |
| 157 | } | 156 | } |
| 158 | 157 | ||
| 159 | void snled27351_set_value(int index, uint8_t value) { | 158 | void snled27351_set_value(int index, uint8_t value) { |
| @@ -192,22 +191,22 @@ void snled27351_set_led_control_register(uint8_t index, bool value) { | |||
| 192 | g_led_control_registers_update_required[led.driver] = true; | 191 | g_led_control_registers_update_required[led.driver] = true; |
| 193 | } | 192 | } |
| 194 | 193 | ||
| 195 | void snled27351_update_pwm_buffers(uint8_t addr, uint8_t index) { | 194 | void snled27351_update_pwm_buffers(uint8_t index) { |
| 196 | if (g_pwm_buffer_update_required[index]) { | 195 | if (g_pwm_buffer_update_required[index]) { |
| 197 | snled27351_select_page(addr, SNLED27351_COMMAND_PWM); | 196 | snled27351_select_page(index, SNLED27351_COMMAND_PWM); |
| 198 | 197 | ||
| 199 | snled27351_write_pwm_buffer(addr, index); | 198 | snled27351_write_pwm_buffer(index); |
| 200 | 199 | ||
| 201 | g_pwm_buffer_update_required[index] = false; | 200 | g_pwm_buffer_update_required[index] = false; |
| 202 | } | 201 | } |
| 203 | } | 202 | } |
| 204 | 203 | ||
| 205 | void snled27351_update_led_control_registers(uint8_t addr, uint8_t index) { | 204 | void snled27351_update_led_control_registers(uint8_t index) { |
| 206 | if (g_led_control_registers_update_required[index]) { | 205 | if (g_led_control_registers_update_required[index]) { |
| 207 | snled27351_select_page(addr, SNLED27351_COMMAND_LED_CONTROL); | 206 | snled27351_select_page(index, SNLED27351_COMMAND_LED_CONTROL); |
| 208 | 207 | ||
| 209 | for (uint8_t i = 0; i < SNLED27351_LED_CONTROL_REGISTER_COUNT; i++) { | 208 | for (uint8_t i = 0; i < SNLED27351_LED_CONTROL_REGISTER_COUNT; i++) { |
| 210 | snled27351_write_register(addr, i, g_led_control_registers[index][i]); | 209 | snled27351_write_register(index, i, g_led_control_registers[index][i]); |
| 211 | } | 210 | } |
| 212 | 211 | ||
| 213 | g_led_control_registers_update_required[index] = false; | 212 | g_led_control_registers_update_required[index] = false; |
| @@ -215,30 +214,23 @@ void snled27351_update_led_control_registers(uint8_t addr, uint8_t index) { | |||
| 215 | } | 214 | } |
| 216 | 215 | ||
| 217 | void snled27351_flush(void) { | 216 | void snled27351_flush(void) { |
| 218 | snled27351_update_pwm_buffers(SNLED27351_I2C_ADDRESS_1, 0); | 217 | for (uint8_t i = 0; i < SNLED27351_DRIVER_COUNT; i++) { |
| 219 | #if defined(SNLED27351_I2C_ADDRESS_2) | 218 | snled27351_update_pwm_buffers(i); |
| 220 | snled27351_update_pwm_buffers(SNLED27351_I2C_ADDRESS_2, 1); | 219 | } |
| 221 | # if defined(SNLED27351_I2C_ADDRESS_3) | ||
| 222 | snled27351_update_pwm_buffers(SNLED27351_I2C_ADDRESS_3, 2); | ||
| 223 | # if defined(SNLED27351_I2C_ADDRESS_4) | ||
| 224 | snled27351_update_pwm_buffers(SNLED27351_I2C_ADDRESS_4, 3); | ||
| 225 | # endif | ||
| 226 | # endif | ||
| 227 | #endif | ||
| 228 | } | 220 | } |
| 229 | 221 | ||
| 230 | void snled27351_sw_return_normal(uint8_t addr) { | 222 | void snled27351_sw_return_normal(uint8_t index) { |
| 231 | snled27351_select_page(addr, SNLED27351_COMMAND_FUNCTION); | 223 | snled27351_select_page(index, SNLED27351_COMMAND_FUNCTION); |
| 232 | 224 | ||
| 233 | // Setting LED driver to normal mode | 225 | // Setting LED driver to normal mode |
| 234 | snled27351_write_register(addr, SNLED27351_FUNCTION_REG_SOFTWARE_SHUTDOWN, SNLED27351_SOFTWARE_SHUTDOWN_SSD_NORMAL); | 226 | snled27351_write_register(index, SNLED27351_FUNCTION_REG_SOFTWARE_SHUTDOWN, SNLED27351_SOFTWARE_SHUTDOWN_SSD_NORMAL); |
| 235 | } | 227 | } |
| 236 | 228 | ||
| 237 | void snled27351_sw_shutdown(uint8_t addr) { | 229 | void snled27351_sw_shutdown(uint8_t index) { |
| 238 | snled27351_select_page(addr, SNLED27351_COMMAND_FUNCTION); | 230 | snled27351_select_page(index, SNLED27351_COMMAND_FUNCTION); |
| 239 | 231 | ||
| 240 | // Setting LED driver to shutdown mode | 232 | // Setting LED driver to shutdown mode |
| 241 | snled27351_write_register(addr, SNLED27351_FUNCTION_REG_SOFTWARE_SHUTDOWN, SNLED27351_SOFTWARE_SHUTDOWN_SSD_SHUTDOWN); | 233 | snled27351_write_register(index, SNLED27351_FUNCTION_REG_SOFTWARE_SHUTDOWN, SNLED27351_SOFTWARE_SHUTDOWN_SSD_SHUTDOWN); |
| 242 | // Write SW Sleep Register | 234 | // Write SW Sleep Register |
| 243 | snled27351_write_register(addr, SNLED27351_FUNCTION_REG_SOFTWARE_SLEEP, SNLED27351_SOFTWARE_SLEEP_ENABLE); | 235 | snled27351_write_register(index, SNLED27351_FUNCTION_REG_SOFTWARE_SLEEP, SNLED27351_SOFTWARE_SLEEP_ENABLE); |
| 244 | } | 236 | } |
diff --git a/drivers/led/snled27351-mono.h b/drivers/led/snled27351-mono.h index 3a22115623..a5f3c3578c 100644 --- a/drivers/led/snled27351-mono.h +++ b/drivers/led/snled27351-mono.h | |||
| @@ -154,9 +154,9 @@ typedef struct snled27351_led_t { | |||
| 154 | extern const snled27351_led_t PROGMEM g_snled27351_leds[SNLED27351_LED_COUNT]; | 154 | extern const snled27351_led_t PROGMEM g_snled27351_leds[SNLED27351_LED_COUNT]; |
| 155 | 155 | ||
| 156 | void snled27351_init_drivers(void); | 156 | void snled27351_init_drivers(void); |
| 157 | void snled27351_init(uint8_t addr); | 157 | void snled27351_init(uint8_t index); |
| 158 | void snled27351_select_page(uint8_t addr, uint8_t page); | 158 | void snled27351_select_page(uint8_t index, uint8_t page); |
| 159 | void snled27351_write_register(uint8_t addr, uint8_t reg, uint8_t data); | 159 | void snled27351_write_register(uint8_t index, uint8_t reg, uint8_t data); |
| 160 | 160 | ||
| 161 | void snled27351_set_value(int index, uint8_t value); | 161 | void snled27351_set_value(int index, uint8_t value); |
| 162 | void snled27351_set_value_all(uint8_t value); | 162 | void snled27351_set_value_all(uint8_t value); |
| @@ -167,13 +167,13 @@ void snled27351_set_led_control_register(uint8_t index, bool value); | |||
| 167 | // (eg. from a timer interrupt). | 167 | // (eg. from a timer interrupt). |
| 168 | // Call this while idle (in between matrix scans). | 168 | // Call this while idle (in between matrix scans). |
| 169 | // If the buffer is dirty, it will update the driver with the buffer. | 169 | // If the buffer is dirty, it will update the driver with the buffer. |
| 170 | void snled27351_update_pwm_buffers(uint8_t addr, uint8_t index); | 170 | void snled27351_update_pwm_buffers(uint8_t index); |
| 171 | void snled27351_update_led_control_registers(uint8_t addr, uint8_t index); | 171 | void snled27351_update_led_control_registers(uint8_t index); |
| 172 | 172 | ||
| 173 | void snled27351_flush(void); | 173 | void snled27351_flush(void); |
| 174 | 174 | ||
| 175 | void snled27351_sw_return_normal(uint8_t addr); | 175 | void snled27351_sw_return_normal(uint8_t index); |
| 176 | void snled27351_sw_shutdown(uint8_t addr); | 176 | void snled27351_sw_shutdown(uint8_t index); |
| 177 | 177 | ||
| 178 | #define A_1 0x00 | 178 | #define A_1 0x00 |
| 179 | #define A_2 0x01 | 179 | #define A_2 0x01 |
diff --git a/drivers/led/snled27351.c b/drivers/led/snled27351.c index 662335afd2..31b69de388 100644 --- a/drivers/led/snled27351.c +++ b/drivers/led/snled27351.c | |||
| @@ -37,6 +37,19 @@ | |||
| 37 | { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } | 37 | { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } |
| 38 | #endif | 38 | #endif |
| 39 | 39 | ||
| 40 | const uint8_t i2c_addresses[SNLED27351_DRIVER_COUNT] = { | ||
| 41 | SNLED27351_I2C_ADDRESS_1, | ||
| 42 | #ifdef SNLED27351_I2C_ADDRESS_2 | ||
| 43 | SNLED27351_I2C_ADDRESS_2, | ||
| 44 | # ifdef SNLED27351_I2C_ADDRESS_3 | ||
| 45 | SNLED27351_I2C_ADDRESS_3, | ||
| 46 | # ifdef SNLED27351_I2C_ADDRESS_4 | ||
| 47 | SNLED27351_I2C_ADDRESS_4, | ||
| 48 | # endif | ||
| 49 | # endif | ||
| 50 | #endif | ||
| 51 | }; | ||
| 52 | |||
| 40 | // These buffers match the SNLED27351 PWM registers. | 53 | // These buffers match the SNLED27351 PWM registers. |
| 41 | // The control buffers match the PG0 LED On/Off registers. | 54 | // The control buffers match the PG0 LED On/Off registers. |
| 42 | // Storing them like this is optimal for I2C transfers to the registers. | 55 | // Storing them like this is optimal for I2C transfers to the registers. |
| @@ -49,21 +62,21 @@ bool g_pwm_buffer_update_required[SNLED27351_DRIVER_COUNT] = {false}; | |||
| 49 | uint8_t g_led_control_registers[SNLED27351_DRIVER_COUNT][SNLED27351_LED_CONTROL_REGISTER_COUNT] = {0}; | 62 | uint8_t g_led_control_registers[SNLED27351_DRIVER_COUNT][SNLED27351_LED_CONTROL_REGISTER_COUNT] = {0}; |
| 50 | bool g_led_control_registers_update_required[SNLED27351_DRIVER_COUNT] = {false}; | 63 | bool g_led_control_registers_update_required[SNLED27351_DRIVER_COUNT] = {false}; |
| 51 | 64 | ||
| 52 | void snled27351_write_register(uint8_t addr, uint8_t reg, uint8_t data) { | 65 | void snled27351_write_register(uint8_t index, uint8_t reg, uint8_t data) { |
| 53 | #if SNLED27351_I2C_PERSISTENCE > 0 | 66 | #if SNLED27351_I2C_PERSISTENCE > 0 |
| 54 | for (uint8_t i = 0; i < SNLED27351_I2C_PERSISTENCE; i++) { | 67 | for (uint8_t i = 0; i < SNLED27351_I2C_PERSISTENCE; i++) { |
| 55 | if (i2c_write_register(addr << 1, reg, &data, 1, SNLED27351_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; | 68 | if (i2c_write_register(i2c_addresses[index] << 1, reg, &data, 1, SNLED27351_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; |
| 56 | } | 69 | } |
| 57 | #else | 70 | #else |
| 58 | i2c_write_register(addr << 1, reg, &data, 1, SNLED27351_I2C_TIMEOUT); | 71 | i2c_write_register(i2c_addresses[index] << 1, reg, &data, 1, SNLED27351_I2C_TIMEOUT); |
| 59 | #endif | 72 | #endif |
| 60 | } | 73 | } |
| 61 | 74 | ||
| 62 | void snled27351_select_page(uint8_t addr, uint8_t page) { | 75 | void snled27351_select_page(uint8_t index, uint8_t page) { |
| 63 | snled27351_write_register(addr, SNLED27351_REG_COMMAND, page); | 76 | snled27351_write_register(index, SNLED27351_REG_COMMAND, page); |
| 64 | } | 77 | } |
| 65 | 78 | ||
| 66 | void snled27351_write_pwm_buffer(uint8_t addr, uint8_t index) { | 79 | void snled27351_write_pwm_buffer(uint8_t index) { |
| 67 | // Assumes PG1 is already selected. | 80 | // Assumes PG1 is already selected. |
| 68 | // Transmit PWM registers in 12 transfers of 16 bytes. | 81 | // Transmit PWM registers in 12 transfers of 16 bytes. |
| 69 | 82 | ||
| @@ -71,10 +84,10 @@ void snled27351_write_pwm_buffer(uint8_t addr, uint8_t index) { | |||
| 71 | for (uint8_t i = 0; i < SNLED27351_PWM_REGISTER_COUNT; i += 16) { | 84 | for (uint8_t i = 0; i < SNLED27351_PWM_REGISTER_COUNT; i += 16) { |
| 72 | #if SNLED27351_I2C_PERSISTENCE > 0 | 85 | #if SNLED27351_I2C_PERSISTENCE > 0 |
| 73 | for (uint8_t j = 0; j < SNLED27351_I2C_PERSISTENCE; j++) { | 86 | for (uint8_t j = 0; j < SNLED27351_I2C_PERSISTENCE; j++) { |
| 74 | if (i2c_write_register(addr << 1, i, g_pwm_buffer[index] + i, 16, SNLED27351_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; | 87 | if (i2c_write_register(i2c_addresses[index] << 1, i, g_pwm_buffer[index] + i, 16, SNLED27351_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; |
| 75 | } | 88 | } |
| 76 | #else | 89 | #else |
| 77 | i2c_write_register(addr << 1, i, g_pwm_buffer[index] + i, 16, SNLED27351_I2C_TIMEOUT); | 90 | i2c_write_register(i2c_addresses[index] << 1, i, g_pwm_buffer[index] + i, 16, SNLED27351_I2C_TIMEOUT); |
| 78 | #endif | 91 | #endif |
| 79 | } | 92 | } |
| 80 | } | 93 | } |
| @@ -82,78 +95,64 @@ void snled27351_write_pwm_buffer(uint8_t addr, uint8_t index) { | |||
| 82 | void snled27351_init_drivers(void) { | 95 | void snled27351_init_drivers(void) { |
| 83 | i2c_init(); | 96 | i2c_init(); |
| 84 | 97 | ||
| 85 | snled27351_init(SNLED27351_I2C_ADDRESS_1); | 98 | for (uint8_t i = 0; i < SNLED27351_DRIVER_COUNT; i++) { |
| 86 | #if defined(SNLED27351_I2C_ADDRESS_2) | 99 | snled27351_init(i); |
| 87 | snled27351_init(SNLED27351_I2C_ADDRESS_2); | 100 | } |
| 88 | # if defined(SNLED27351_I2C_ADDRESS_3) | ||
| 89 | snled27351_init(SNLED27351_I2C_ADDRESS_3); | ||
| 90 | # if defined(SNLED27351_I2C_ADDRESS_4) | ||
| 91 | snled27351_init(SNLED27351_I2C_ADDRESS_4); | ||
| 92 | # endif | ||
| 93 | # endif | ||
| 94 | #endif | ||
| 95 | 101 | ||
| 96 | for (int i = 0; i < SNLED27351_LED_COUNT; i++) { | 102 | for (int i = 0; i < SNLED27351_LED_COUNT; i++) { |
| 97 | snled27351_set_led_control_register(i, true, true, true); | 103 | snled27351_set_led_control_register(i, true, true, true); |
| 98 | } | 104 | } |
| 99 | 105 | ||
| 100 | snled27351_update_led_control_registers(SNLED27351_I2C_ADDRESS_1, 0); | 106 | for (uint8_t i = 0; i < SNLED27351_DRIVER_COUNT; i++) { |
| 101 | #if defined(SNLED27351_I2C_ADDRESS_2) | 107 | snled27351_update_led_control_registers(i); |
| 102 | snled27351_update_led_control_registers(SNLED27351_I2C_ADDRESS_2, 1); | 108 | } |
| 103 | # if defined(SNLED27351_I2C_ADDRESS_3) | ||
| 104 | snled27351_update_led_control_registers(SNLED27351_I2C_ADDRESS_3, 2); | ||
| 105 | # if defined(SNLED27351_I2C_ADDRESS_4) | ||
| 106 | snled27351_update_led_control_registers(SNLED27351_I2C_ADDRESS_4, 3); | ||
| 107 | # endif | ||
| 108 | # endif | ||
| 109 | #endif | ||
| 110 | } | 109 | } |
| 111 | 110 | ||
| 112 | void snled27351_init(uint8_t addr) { | 111 | void snled27351_init(uint8_t index) { |
| 113 | snled27351_select_page(addr, SNLED27351_COMMAND_FUNCTION); | 112 | snled27351_select_page(index, SNLED27351_COMMAND_FUNCTION); |
| 114 | 113 | ||
| 115 | // Setting LED driver to shutdown mode | 114 | // Setting LED driver to shutdown mode |
| 116 | snled27351_write_register(addr, SNLED27351_FUNCTION_REG_SOFTWARE_SHUTDOWN, SNLED27351_SOFTWARE_SHUTDOWN_SSD_SHUTDOWN); | 115 | snled27351_write_register(index, SNLED27351_FUNCTION_REG_SOFTWARE_SHUTDOWN, SNLED27351_SOFTWARE_SHUTDOWN_SSD_SHUTDOWN); |
| 117 | // Setting internal channel pulldown/pullup | 116 | // Setting internal channel pulldown/pullup |
| 118 | snled27351_write_register(addr, SNLED27351_FUNCTION_REG_PULLDOWNUP, SNLED27351_PULLDOWNUP_ALL_ENABLED); | 117 | snled27351_write_register(index, SNLED27351_FUNCTION_REG_PULLDOWNUP, SNLED27351_PULLDOWNUP_ALL_ENABLED); |
| 119 | // Select number of scan phase | 118 | // Select number of scan phase |
| 120 | snled27351_write_register(addr, SNLED27351_FUNCTION_REG_SCAN_PHASE, SNLED27351_PHASE_CHANNEL); | 119 | snled27351_write_register(index, SNLED27351_FUNCTION_REG_SCAN_PHASE, SNLED27351_PHASE_CHANNEL); |
| 121 | // Setting PWM Delay Phase | 120 | // Setting PWM Delay Phase |
| 122 | snled27351_write_register(addr, SNLED27351_FUNCTION_REG_SLEW_RATE_CONTROL_MODE_1, SNLED27351_SLEW_RATE_CONTROL_MODE_1_PDP_ENABLE); | 121 | snled27351_write_register(index, SNLED27351_FUNCTION_REG_SLEW_RATE_CONTROL_MODE_1, SNLED27351_SLEW_RATE_CONTROL_MODE_1_PDP_ENABLE); |
| 123 | // Setting Driving/Sinking Channel Slew Rate | 122 | // Setting Driving/Sinking Channel Slew Rate |
| 124 | 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); | 123 | snled27351_write_register(index, SNLED27351_FUNCTION_REG_SLEW_RATE_CONTROL_MODE_2, SNLED27351_SLEW_RATE_CONTROL_MODE_2_DSL_ENABLE | SNLED27351_SLEW_RATE_CONTROL_MODE_2_SSL_ENABLE); |
| 125 | // Setting Iref | 124 | // Setting Iref |
| 126 | snled27351_write_register(addr, SNLED27351_FUNCTION_REG_SOFTWARE_SLEEP, 0); | 125 | snled27351_write_register(index, SNLED27351_FUNCTION_REG_SOFTWARE_SLEEP, 0); |
| 127 | 126 | ||
| 128 | snled27351_select_page(addr, SNLED27351_COMMAND_LED_CONTROL); | 127 | snled27351_select_page(index, SNLED27351_COMMAND_LED_CONTROL); |
| 129 | 128 | ||
| 130 | for (int i = 0; i < SNLED27351_LED_CONTROL_ON_OFF_LENGTH; i++) { | 129 | for (int i = 0; i < SNLED27351_LED_CONTROL_ON_OFF_LENGTH; i++) { |
| 131 | snled27351_write_register(addr, i, 0x00); | 130 | snled27351_write_register(index, i, 0x00); |
| 132 | } | 131 | } |
| 133 | 132 | ||
| 134 | snled27351_select_page(addr, SNLED27351_COMMAND_PWM); | 133 | snled27351_select_page(index, SNLED27351_COMMAND_PWM); |
| 135 | 134 | ||
| 136 | for (int i = 0; i < SNLED27351_LED_CURRENT_TUNE_LENGTH; i++) { | 135 | for (int i = 0; i < SNLED27351_LED_CURRENT_TUNE_LENGTH; i++) { |
| 137 | snled27351_write_register(addr, i, 0x00); | 136 | snled27351_write_register(index, i, 0x00); |
| 138 | } | 137 | } |
| 139 | 138 | ||
| 140 | snled27351_select_page(addr, SNLED27351_COMMAND_CURRENT_TUNE); | 139 | snled27351_select_page(index, SNLED27351_COMMAND_CURRENT_TUNE); |
| 141 | 140 | ||
| 142 | uint8_t current_tune_reg_list[SNLED27351_LED_CURRENT_TUNE_LENGTH] = SNLED27351_CURRENT_TUNE; | 141 | uint8_t current_tune_reg_list[SNLED27351_LED_CURRENT_TUNE_LENGTH] = SNLED27351_CURRENT_TUNE; |
| 143 | for (int i = 0; i < SNLED27351_LED_CURRENT_TUNE_LENGTH; i++) { | 142 | for (int i = 0; i < SNLED27351_LED_CURRENT_TUNE_LENGTH; i++) { |
| 144 | snled27351_write_register(addr, i, current_tune_reg_list[i]); | 143 | snled27351_write_register(index, i, current_tune_reg_list[i]); |
| 145 | } | 144 | } |
| 146 | 145 | ||
| 147 | snled27351_select_page(addr, SNLED27351_COMMAND_LED_CONTROL); | 146 | snled27351_select_page(index, SNLED27351_COMMAND_LED_CONTROL); |
| 148 | 147 | ||
| 149 | for (int i = 0; i < SNLED27351_LED_CONTROL_ON_OFF_LENGTH; i++) { | 148 | for (int i = 0; i < SNLED27351_LED_CONTROL_ON_OFF_LENGTH; i++) { |
| 150 | snled27351_write_register(addr, i, 0xFF); | 149 | snled27351_write_register(index, i, 0xFF); |
| 151 | } | 150 | } |
| 152 | 151 | ||
| 153 | snled27351_select_page(addr, SNLED27351_COMMAND_FUNCTION); | 152 | snled27351_select_page(index, SNLED27351_COMMAND_FUNCTION); |
| 154 | 153 | ||
| 155 | // Setting LED driver to normal mode | 154 | // Setting LED driver to normal mode |
| 156 | snled27351_write_register(addr, SNLED27351_FUNCTION_REG_SOFTWARE_SHUTDOWN, SNLED27351_SOFTWARE_SHUTDOWN_SSD_NORMAL); | 155 | snled27351_write_register(index, SNLED27351_FUNCTION_REG_SOFTWARE_SHUTDOWN, SNLED27351_SOFTWARE_SHUTDOWN_SSD_NORMAL); |
| 157 | } | 156 | } |
| 158 | 157 | ||
| 159 | void snled27351_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { | 158 | void snled27351_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { |
| @@ -208,22 +207,22 @@ void snled27351_set_led_control_register(uint8_t index, bool red, bool green, bo | |||
| 208 | g_led_control_registers_update_required[led.driver] = true; | 207 | g_led_control_registers_update_required[led.driver] = true; |
| 209 | } | 208 | } |
| 210 | 209 | ||
| 211 | void snled27351_update_pwm_buffers(uint8_t addr, uint8_t index) { | 210 | void snled27351_update_pwm_buffers(uint8_t index) { |
| 212 | if (g_pwm_buffer_update_required[index]) { | 211 | if (g_pwm_buffer_update_required[index]) { |
| 213 | snled27351_select_page(addr, SNLED27351_COMMAND_PWM); | 212 | snled27351_select_page(index, SNLED27351_COMMAND_PWM); |
| 214 | 213 | ||
| 215 | snled27351_write_pwm_buffer(addr, index); | 214 | snled27351_write_pwm_buffer(index); |
| 216 | 215 | ||
| 217 | g_pwm_buffer_update_required[index] = false; | 216 | g_pwm_buffer_update_required[index] = false; |
| 218 | } | 217 | } |
| 219 | } | 218 | } |
| 220 | 219 | ||
| 221 | void snled27351_update_led_control_registers(uint8_t addr, uint8_t index) { | 220 | void snled27351_update_led_control_registers(uint8_t index) { |
| 222 | if (g_led_control_registers_update_required[index]) { | 221 | if (g_led_control_registers_update_required[index]) { |
| 223 | snled27351_select_page(addr, SNLED27351_COMMAND_LED_CONTROL); | 222 | snled27351_select_page(index, SNLED27351_COMMAND_LED_CONTROL); |
| 224 | 223 | ||
| 225 | for (uint8_t i = 0; i < SNLED27351_LED_CONTROL_REGISTER_COUNT; i++) { | 224 | for (uint8_t i = 0; i < SNLED27351_LED_CONTROL_REGISTER_COUNT; i++) { |
| 226 | snled27351_write_register(addr, i, g_led_control_registers[index][i]); | 225 | snled27351_write_register(index, i, g_led_control_registers[index][i]); |
| 227 | } | 226 | } |
| 228 | 227 | ||
| 229 | g_led_control_registers_update_required[index] = false; | 228 | g_led_control_registers_update_required[index] = false; |
| @@ -231,30 +230,23 @@ void snled27351_update_led_control_registers(uint8_t addr, uint8_t index) { | |||
| 231 | } | 230 | } |
| 232 | 231 | ||
| 233 | void snled27351_flush(void) { | 232 | void snled27351_flush(void) { |
| 234 | snled27351_update_pwm_buffers(SNLED27351_I2C_ADDRESS_1, 0); | 233 | for (uint8_t i = 0; i < SNLED27351_DRIVER_COUNT; i++) { |
| 235 | #if defined(SNLED27351_I2C_ADDRESS_2) | 234 | snled27351_update_pwm_buffers(i); |
| 236 | snled27351_update_pwm_buffers(SNLED27351_I2C_ADDRESS_2, 1); | 235 | } |
| 237 | # if defined(SNLED27351_I2C_ADDRESS_3) | ||
| 238 | snled27351_update_pwm_buffers(SNLED27351_I2C_ADDRESS_3, 2); | ||
| 239 | # if defined(SNLED27351_I2C_ADDRESS_4) | ||
| 240 | snled27351_update_pwm_buffers(SNLED27351_I2C_ADDRESS_4, 3); | ||
| 241 | # endif | ||
| 242 | # endif | ||
| 243 | #endif | ||
| 244 | } | 236 | } |
| 245 | 237 | ||
| 246 | void snled27351_sw_return_normal(uint8_t addr) { | 238 | void snled27351_sw_return_normal(uint8_t index) { |
| 247 | snled27351_select_page(addr, SNLED27351_COMMAND_FUNCTION); | 239 | snled27351_select_page(index, SNLED27351_COMMAND_FUNCTION); |
| 248 | 240 | ||
| 249 | // Setting LED driver to normal mode | 241 | // Setting LED driver to normal mode |
| 250 | snled27351_write_register(addr, SNLED27351_FUNCTION_REG_SOFTWARE_SHUTDOWN, SNLED27351_SOFTWARE_SHUTDOWN_SSD_NORMAL); | 242 | snled27351_write_register(index, SNLED27351_FUNCTION_REG_SOFTWARE_SHUTDOWN, SNLED27351_SOFTWARE_SHUTDOWN_SSD_NORMAL); |
| 251 | } | 243 | } |
| 252 | 244 | ||
| 253 | void snled27351_sw_shutdown(uint8_t addr) { | 245 | void snled27351_sw_shutdown(uint8_t index) { |
| 254 | snled27351_select_page(addr, SNLED27351_COMMAND_FUNCTION); | 246 | snled27351_select_page(index, SNLED27351_COMMAND_FUNCTION); |
| 255 | 247 | ||
| 256 | // Setting LED driver to shutdown mode | 248 | // Setting LED driver to shutdown mode |
| 257 | snled27351_write_register(addr, SNLED27351_FUNCTION_REG_SOFTWARE_SHUTDOWN, SNLED27351_SOFTWARE_SHUTDOWN_SSD_SHUTDOWN); | 249 | snled27351_write_register(index, SNLED27351_FUNCTION_REG_SOFTWARE_SHUTDOWN, SNLED27351_SOFTWARE_SHUTDOWN_SSD_SHUTDOWN); |
| 258 | // Write SW Sleep Register | 250 | // Write SW Sleep Register |
| 259 | snled27351_write_register(addr, SNLED27351_FUNCTION_REG_SOFTWARE_SLEEP, SNLED27351_SOFTWARE_SLEEP_ENABLE); | 251 | snled27351_write_register(index, SNLED27351_FUNCTION_REG_SOFTWARE_SLEEP, SNLED27351_SOFTWARE_SLEEP_ENABLE); |
| 260 | } | 252 | } |
diff --git a/drivers/led/snled27351.h b/drivers/led/snled27351.h index 4b811719d9..79d601ca2d 100644 --- a/drivers/led/snled27351.h +++ b/drivers/led/snled27351.h | |||
| @@ -168,9 +168,9 @@ typedef struct snled27351_led_t { | |||
| 168 | extern const snled27351_led_t PROGMEM g_snled27351_leds[SNLED27351_LED_COUNT]; | 168 | extern const snled27351_led_t PROGMEM g_snled27351_leds[SNLED27351_LED_COUNT]; |
| 169 | 169 | ||
| 170 | void snled27351_init_drivers(void); | 170 | void snled27351_init_drivers(void); |
| 171 | void snled27351_init(uint8_t addr); | 171 | void snled27351_init(uint8_t index); |
| 172 | void snled27351_select_page(uint8_t addr, uint8_t page); | 172 | void snled27351_select_page(uint8_t index, uint8_t page); |
| 173 | void snled27351_write_register(uint8_t addr, uint8_t reg, uint8_t data); | 173 | void snled27351_write_register(uint8_t index, uint8_t reg, uint8_t data); |
| 174 | 174 | ||
| 175 | void snled27351_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); | 175 | void snled27351_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); |
| 176 | void snled27351_set_color_all(uint8_t red, uint8_t green, uint8_t blue); | 176 | void snled27351_set_color_all(uint8_t red, uint8_t green, uint8_t blue); |
| @@ -181,13 +181,13 @@ void snled27351_set_led_control_register(uint8_t index, bool red, bool green, bo | |||
| 181 | // (eg. from a timer interrupt). | 181 | // (eg. from a timer interrupt). |
| 182 | // Call this while idle (in between matrix scans). | 182 | // Call this while idle (in between matrix scans). |
| 183 | // If the buffer is dirty, it will update the driver with the buffer. | 183 | // If the buffer is dirty, it will update the driver with the buffer. |
| 184 | void snled27351_update_pwm_buffers(uint8_t addr, uint8_t index); | 184 | void snled27351_update_pwm_buffers(uint8_t index); |
| 185 | void snled27351_update_led_control_registers(uint8_t addr, uint8_t index); | 185 | void snled27351_update_led_control_registers(uint8_t index); |
| 186 | 186 | ||
| 187 | void snled27351_flush(void); | 187 | void snled27351_flush(void); |
| 188 | 188 | ||
| 189 | void snled27351_sw_return_normal(uint8_t addr); | 189 | void snled27351_sw_return_normal(uint8_t index); |
| 190 | void snled27351_sw_shutdown(uint8_t addr); | 190 | void snled27351_sw_shutdown(uint8_t index); |
| 191 | 191 | ||
| 192 | #define A_1 0x00 | 192 | #define A_1 0x00 |
| 193 | #define A_2 0x01 | 193 | #define A_2 0x01 |
