diff options
| author | Ryan <fauxpark@gmail.com> | 2024-01-01 21:44:18 +1100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-01-01 21:44:18 +1100 |
| commit | 0a6913b68274c03302b09466a79b99efffd35e59 (patch) | |
| tree | 60c1075ded48a51727f2d2e13a1450f34d370951 | |
| parent | a88dd675bf3e1dedac2ceb7df779e0fb6931948a (diff) | |
LED drivers: extract IS31FL3746A from IS31COMMON (#22637)
| -rw-r--r-- | builddefs/common_features.mk | 6 | ||||
| -rw-r--r-- | drivers/led/issi/is31fl3746.h | 198 | ||||
| -rw-r--r-- | drivers/led/issi/is31fl3746a-simple.c | 208 | ||||
| -rw-r--r-- | drivers/led/issi/is31fl3746a-simple.h | 192 | ||||
| -rw-r--r-- | drivers/led/issi/is31fl3746a.c | 212 | ||||
| -rw-r--r-- | drivers/led/issi/is31fl3746a.h | 194 | ||||
| -rw-r--r-- | drivers/led/issi/is31flcommon.h | 5 | ||||
| -rw-r--r-- | quantum/led_matrix/led_matrix_drivers.c | 8 | ||||
| -rw-r--r-- | quantum/led_matrix/led_matrix_drivers.h | 2 | ||||
| -rw-r--r-- | quantum/rgb_matrix/rgb_matrix_drivers.c | 8 | ||||
| -rw-r--r-- | quantum/rgb_matrix/rgb_matrix_drivers.h | 2 |
11 files changed, 828 insertions, 207 deletions
diff --git a/builddefs/common_features.mk b/builddefs/common_features.mk index d5446a54c8..cfdc63f1d4 100644 --- a/builddefs/common_features.mk +++ b/builddefs/common_features.mk | |||
| @@ -414,10 +414,9 @@ ifeq ($(strip $(LED_MATRIX_ENABLE)), yes) | |||
| 414 | endif | 414 | endif |
| 415 | 415 | ||
| 416 | ifeq ($(strip $(LED_MATRIX_DRIVER)), is31fl3746a) | 416 | ifeq ($(strip $(LED_MATRIX_DRIVER)), is31fl3746a) |
| 417 | OPT_DEFS += -DIS31FLCOMMON | ||
| 418 | I2C_DRIVER_REQUIRED = yes | 417 | I2C_DRIVER_REQUIRED = yes |
| 419 | COMMON_VPATH += $(DRIVER_PATH)/led/issi | 418 | COMMON_VPATH += $(DRIVER_PATH)/led/issi |
| 420 | SRC += is31flcommon.c | 419 | SRC += is31fl3746a-simple.c |
| 421 | endif | 420 | endif |
| 422 | 421 | ||
| 423 | ifeq ($(strip $(LED_MATRIX_DRIVER)), snled27351) | 422 | ifeq ($(strip $(LED_MATRIX_DRIVER)), snled27351) |
| @@ -518,10 +517,9 @@ ifeq ($(strip $(RGB_MATRIX_ENABLE)), yes) | |||
| 518 | endif | 517 | endif |
| 519 | 518 | ||
| 520 | ifeq ($(strip $(RGB_MATRIX_DRIVER)), is31fl3746a) | 519 | ifeq ($(strip $(RGB_MATRIX_DRIVER)), is31fl3746a) |
| 521 | OPT_DEFS += -DIS31FLCOMMON | ||
| 522 | I2C_DRIVER_REQUIRED = yes | 520 | I2C_DRIVER_REQUIRED = yes |
| 523 | COMMON_VPATH += $(DRIVER_PATH)/led/issi | 521 | COMMON_VPATH += $(DRIVER_PATH)/led/issi |
| 524 | SRC += is31flcommon.c | 522 | SRC += is31fl3746a.c |
| 525 | endif | 523 | endif |
| 526 | 524 | ||
| 527 | ifeq ($(strip $(RGB_MATRIX_DRIVER)), snled27351) | 525 | ifeq ($(strip $(RGB_MATRIX_DRIVER)), snled27351) |
diff --git a/drivers/led/issi/is31fl3746.h b/drivers/led/issi/is31fl3746.h deleted file mode 100644 index f89f281533..0000000000 --- a/drivers/led/issi/is31fl3746.h +++ /dev/null | |||
| @@ -1,198 +0,0 @@ | |||
| 1 | /* Copyright 2017 Jason Williams | ||
| 2 | * Copyright 2018 Jack Humbert | ||
| 3 | * Copyright 2018 Yiancar | ||
| 4 | * Copyright 2020 MelGeek | ||
| 5 | * Copyright 2021 MasterSpoon | ||
| 6 | * | ||
| 7 | * This program is free software: you can redistribute it and/or modify | ||
| 8 | * it under the terms of the GNU General Public License as published by | ||
| 9 | * the Free Software Foundation, either version 2 of the License, or | ||
| 10 | * (at your option) any later version. | ||
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License | ||
| 18 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #pragma once | ||
| 22 | |||
| 23 | // This is a 7-bit address, that gets left-shifted and bit 0 | ||
| 24 | // set to 0 for write, 1 for read (as per I2C protocol) | ||
| 25 | // The address will vary depending on your wiring: | ||
| 26 | // 00 <-> GND | ||
| 27 | // 01 <-> SCL | ||
| 28 | // 10 <-> SDA | ||
| 29 | // 11 <-> VCC | ||
| 30 | // ADDR1 represents A1:A0 of the 7-bit address. | ||
| 31 | // ADDR2 represents A3:A2 of the 7-bit address. | ||
| 32 | // The result is: 0b110(ADDR2)(ADDR1) | ||
| 33 | #ifndef DRIVER_ADDR_1 | ||
| 34 | # define DRIVER_ADDR_1 0b1100000 | ||
| 35 | #endif | ||
| 36 | |||
| 37 | // Set defaults for Spread Spectrum Register | ||
| 38 | #ifndef ISSI_SSR_1 | ||
| 39 | # define ISSI_SSR_1 0x00 | ||
| 40 | #endif | ||
| 41 | #ifndef ISSI_SSR_2 | ||
| 42 | # define ISSI_SSR_2 0x00 | ||
| 43 | #endif | ||
| 44 | #ifndef ISSI_SSR_3 | ||
| 45 | # define ISSI_SSR_3 0x00 | ||
| 46 | #endif | ||
| 47 | #ifndef ISSI_SSR_4 | ||
| 48 | # define ISSI_SSR_4 0x00 | ||
| 49 | #endif | ||
| 50 | |||
| 51 | // Command Registers | ||
| 52 | #define ISSI_COMMANDREGISTER_WRITELOCK 0xFE | ||
| 53 | #define ISSI_COMMANDREGISTER 0xFD | ||
| 54 | #define ISSI_IDREGISTER 0xFC | ||
| 55 | #define ISSI_REGISTER_UNLOCK 0xC5 | ||
| 56 | |||
| 57 | // Response Registers | ||
| 58 | #define ISSI_PAGE_PWM 0x00 | ||
| 59 | #define ISSI_PAGE_SCALING 0x01 | ||
| 60 | #define ISSI_PAGE_FUNCTION 0x01 | ||
| 61 | |||
| 62 | // Registers under Function Register | ||
| 63 | #define ISSI_REG_CONFIGURATION 0x50 | ||
| 64 | #define ISSI_REG_GLOBALCURRENT 0x51 | ||
| 65 | #define ISSI_REG_PULLDOWNUP 0x52 | ||
| 66 | #define ISSI_REG_TEMP 0x5F | ||
| 67 | #define ISSI_REG_SSR 0x60 | ||
| 68 | #define ISSI_REG_RESET 0x8F | ||
| 69 | #define ISSI_REG_PWM_ENABLE 0xE0 | ||
| 70 | #define ISSI_REG_PWM_SET 0xE2 | ||
| 71 | |||
| 72 | // Set defaults for Function Registers | ||
| 73 | #ifndef ISSI_CONFIGURATION | ||
| 74 | # define ISSI_CONFIGURATION 0x01 | ||
| 75 | #endif | ||
| 76 | #ifndef ISSI_GLOBALCURRENT | ||
| 77 | # define ISSI_GLOBALCURRENT 0xFF | ||
| 78 | #endif | ||
| 79 | #ifndef ISSI_PULLDOWNUP | ||
| 80 | # define ISSI_PULLDOWNUP 0x33 | ||
| 81 | #endif | ||
| 82 | #ifndef ISSI_TEMP | ||
| 83 | # define ISSI_TEMP 0x00 | ||
| 84 | #endif | ||
| 85 | #ifndef ISSI_PWM_ENABLE | ||
| 86 | # define ISSI_PWM_ENABLE 0x00 | ||
| 87 | #endif | ||
| 88 | #ifndef ISSI_PWM_SET | ||
| 89 | # define ISSI_PWM_SET 0x00 | ||
| 90 | #endif | ||
| 91 | |||
| 92 | // Set defaults for Scaling registers | ||
| 93 | #ifndef ISSI_SCAL_RED | ||
| 94 | # define ISSI_SCAL_RED 0xFF | ||
| 95 | #endif | ||
| 96 | #ifndef ISSI_SCAL_BLUE | ||
| 97 | # define ISSI_SCAL_BLUE 0xFF | ||
| 98 | #endif | ||
| 99 | #ifndef ISSI_SCAL_GREEN | ||
| 100 | # define ISSI_SCAL_GREEN 0xFF | ||
| 101 | #endif | ||
| 102 | #define ISSI_SCAL_RED_OFF 0x00 | ||
| 103 | #define ISSI_SCAL_GREEN_OFF 0x00 | ||
| 104 | #define ISSI_SCAL_BLUE_OFF 0x00 | ||
| 105 | |||
| 106 | #ifndef ISSI_SCAL_LED | ||
| 107 | # define ISSI_SCAL_LED 0xFF | ||
| 108 | #endif | ||
| 109 | #define ISSI_SCAL_LED_OFF 0x00 | ||
| 110 | |||
| 111 | // Set buffer sizes | ||
| 112 | #define ISSI_MAX_LEDS 72 | ||
| 113 | #define ISSI_SCALING_SIZE 72 | ||
| 114 | #define ISSI_PWM_TRF_SIZE 18 | ||
| 115 | #define ISSI_SCALING_TRF_SIZE 18 | ||
| 116 | |||
| 117 | // Location of 1st bit for PWM and Scaling registers | ||
| 118 | #define ISSI_PWM_REG_1ST 0x01 | ||
| 119 | #define ISSI_SCL_REG_1ST 0x01 | ||
| 120 | |||
| 121 | // Map CS SW locations to order in PWM / Scaling buffers | ||
| 122 | // This matches the ORDER in the Datasheet Register not the POSITION | ||
| 123 | // It will always count from 0x00 to (ISSI_MAX_LEDS - 1) | ||
| 124 | #define CS1_SW1 0x00 | ||
| 125 | #define CS2_SW1 0x01 | ||
| 126 | #define CS3_SW1 0x02 | ||
| 127 | #define CS4_SW1 0x03 | ||
| 128 | #define CS5_SW1 0x04 | ||
| 129 | #define CS6_SW1 0x05 | ||
| 130 | #define CS7_SW1 0x06 | ||
| 131 | #define CS8_SW1 0x07 | ||
| 132 | #define CS9_SW1 0x08 | ||
| 133 | #define CS10_SW1 0x09 | ||
| 134 | #define CS11_SW1 0x0A | ||
| 135 | #define CS12_SW1 0x0B | ||
| 136 | #define CS13_SW1 0x0C | ||
| 137 | #define CS14_SW1 0x0D | ||
| 138 | #define CS15_SW1 0x0E | ||
| 139 | #define CS16_SW1 0x0F | ||
| 140 | #define CS17_SW1 0x10 | ||
| 141 | #define CS18_SW1 0x11 | ||
| 142 | |||
| 143 | #define CS1_SW2 0x12 | ||
| 144 | #define CS2_SW2 0x13 | ||
| 145 | #define CS3_SW2 0x14 | ||
| 146 | #define CS4_SW2 0x15 | ||
| 147 | #define CS5_SW2 0x16 | ||
| 148 | #define CS6_SW2 0x17 | ||
| 149 | #define CS7_SW2 0x18 | ||
| 150 | #define CS8_SW2 0x19 | ||
| 151 | #define CS9_SW2 0x1A | ||
| 152 | #define CS10_SW2 0x1B | ||
| 153 | #define CS11_SW2 0x1C | ||
| 154 | #define CS12_SW2 0x1D | ||
| 155 | #define CS13_SW2 0x1E | ||
| 156 | #define CS14_SW2 0x1F | ||
| 157 | #define CS15_SW2 0x20 | ||
| 158 | #define CS16_SW2 0x21 | ||
| 159 | #define CS17_SW2 0x22 | ||
| 160 | #define CS18_SW2 0x23 | ||
| 161 | |||
| 162 | #define CS1_SW3 0x24 | ||
| 163 | #define CS2_SW3 0x25 | ||
| 164 | #define CS3_SW3 0x26 | ||
| 165 | #define CS4_SW3 0x27 | ||
| 166 | #define CS5_SW3 0x28 | ||
| 167 | #define CS6_SW3 0x29 | ||
| 168 | #define CS7_SW3 0x2A | ||
| 169 | #define CS8_SW3 0x2B | ||
| 170 | #define CS9_SW3 0x2C | ||
| 171 | #define CS10_SW3 0x2D | ||
| 172 | #define CS11_SW3 0x2E | ||
| 173 | #define CS12_SW3 0x2F | ||
| 174 | #define CS13_SW3 0x30 | ||
| 175 | #define CS14_SW3 0x31 | ||
| 176 | #define CS15_SW3 0x32 | ||
| 177 | #define CS16_SW3 0x33 | ||
| 178 | #define CS17_SW3 0x34 | ||
| 179 | #define CS18_SW3 0x35 | ||
| 180 | |||
| 181 | #define CS1_SW4 0x36 | ||
| 182 | #define CS2_SW4 0x37 | ||
| 183 | #define CS3_SW4 0x38 | ||
| 184 | #define CS4_SW4 0x39 | ||
| 185 | #define CS5_SW4 0x3A | ||
| 186 | #define CS6_SW4 0x3B | ||
| 187 | #define CS7_SW4 0x3C | ||
| 188 | #define CS8_SW4 0x3D | ||
| 189 | #define CS9_SW4 0x3E | ||
| 190 | #define CS10_SW4 0x3F | ||
| 191 | #define CS11_SW4 0x40 | ||
| 192 | #define CS12_SW4 0x41 | ||
| 193 | #define CS13_SW4 0x42 | ||
| 194 | #define CS14_SW4 0x43 | ||
| 195 | #define CS15_SW4 0x44 | ||
| 196 | #define CS16_SW4 0x45 | ||
| 197 | #define CS17_SW4 0x46 | ||
| 198 | #define CS18_SW4 0x47 | ||
diff --git a/drivers/led/issi/is31fl3746a-simple.c b/drivers/led/issi/is31fl3746a-simple.c new file mode 100644 index 0000000000..3a29c511cb --- /dev/null +++ b/drivers/led/issi/is31fl3746a-simple.c | |||
| @@ -0,0 +1,208 @@ | |||
| 1 | #include "is31fl3746a-simple.h" | ||
| 2 | #include <string.h> | ||
| 3 | #include "i2c_master.h" | ||
| 4 | #include "wait.h" | ||
| 5 | |||
| 6 | #define IS31FL3746A_PWM_REGISTER_COUNT 72 | ||
| 7 | #define IS31FL3746A_SCALING_REGISTER_COUNT 72 | ||
| 8 | |||
| 9 | #ifndef IS31FL3746A_I2C_TIMEOUT | ||
| 10 | # define IS31FL3746A_I2C_TIMEOUT 100 | ||
| 11 | #endif | ||
| 12 | |||
| 13 | #ifndef IS31FL3746A_I2C_PERSISTENCE | ||
| 14 | # define IS31FL3746A_I2C_PERSISTENCE 0 | ||
| 15 | #endif | ||
| 16 | |||
| 17 | #ifndef IS31FL3746A_CONFIGURATION | ||
| 18 | # define IS31FL3746A_CONFIGURATION 0x01 | ||
| 19 | #endif | ||
| 20 | |||
| 21 | #ifndef IS31FL3746A_PWM_FREQUENCY | ||
| 22 | # define IS31FL3746A_PWM_FREQUENCY IS31FL3746A_PWM_FREQUENCY_29K_HZ | ||
| 23 | #endif | ||
| 24 | |||
| 25 | #ifndef IS31FL3746A_SW_PULLDOWN | ||
| 26 | # define IS31FL3746A_SW_PULLDOWN IS31FL3746A_PDR_2K_OHM_SW_OFF | ||
| 27 | #endif | ||
| 28 | |||
| 29 | #ifndef IS31FL3746A_CS_PULLUP | ||
| 30 | # define IS31FL3746A_CS_PULLUP IS31FL3746A_PUR_2K_OHM_CS_OFF | ||
| 31 | #endif | ||
| 32 | |||
| 33 | #ifndef IS31FL3746A_GLOBAL_CURRENT | ||
| 34 | # define IS31FL3746A_GLOBAL_CURRENT 0xFF | ||
| 35 | #endif | ||
| 36 | |||
| 37 | uint8_t i2c_transfer_buffer[20] = {0xFF}; | ||
| 38 | |||
| 39 | uint8_t g_pwm_buffer[IS31FL3746A_DRIVER_COUNT][IS31FL3746A_PWM_REGISTER_COUNT]; | ||
| 40 | bool g_pwm_buffer_update_required[IS31FL3746A_DRIVER_COUNT] = {false}; | ||
| 41 | bool g_scaling_registers_update_required[IS31FL3746A_DRIVER_COUNT] = {false}; | ||
| 42 | |||
| 43 | uint8_t g_scaling_registers[IS31FL3746A_DRIVER_COUNT][IS31FL3746A_SCALING_REGISTER_COUNT]; | ||
| 44 | |||
| 45 | void is31fl3746a_write_register(uint8_t addr, uint8_t reg, uint8_t data) { | ||
| 46 | i2c_transfer_buffer[0] = reg; | ||
| 47 | i2c_transfer_buffer[1] = data; | ||
| 48 | |||
| 49 | #if IS31FL3746A_I2C_PERSISTENCE > 0 | ||
| 50 | for (uint8_t i = 0; i < IS31FL3746A_I2C_PERSISTENCE; i++) { | ||
| 51 | if (i2c_transmit(addr << 1, i2c_transfer_buffer, 2, IS31FL3746A_I2C_TIMEOUT) == 0) break; | ||
| 52 | } | ||
| 53 | #else | ||
| 54 | i2c_transmit(addr << 1, i2c_transfer_buffer, 2, IS31FL3746A_I2C_TIMEOUT); | ||
| 55 | #endif | ||
| 56 | } | ||
| 57 | |||
| 58 | void is31fl3746a_select_page(uint8_t addr, uint8_t page) { | ||
| 59 | is31fl3746a_write_register(addr, IS31FL3746A_REG_COMMAND_WRITE_LOCK, IS31FL3746A_COMMAND_WRITE_LOCK_MAGIC); | ||
| 60 | is31fl3746a_write_register(addr, IS31FL3746A_REG_COMMAND, page); | ||
| 61 | } | ||
| 62 | |||
| 63 | void is31fl3746a_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer) { | ||
| 64 | // Assumes page 0 is already selected. | ||
| 65 | // If any of the transactions fails function returns false. | ||
| 66 | // Transmit PWM registers in 12 transfers of 16 bytes. | ||
| 67 | // i2c_transfer_buffer[] is 20 bytes | ||
| 68 | |||
| 69 | // Iterate over the pwm_buffer contents at 16 byte intervals. | ||
| 70 | for (int i = 0; i < IS31FL3746A_PWM_REGISTER_COUNT; i += 16) { | ||
| 71 | i2c_transfer_buffer[0] = i + 1; | ||
| 72 | // Copy the data from i to i+15. | ||
| 73 | // Device will auto-increment register for data after the first byte | ||
| 74 | // Thus this sets registers 0x00-0x0F, 0x10-0x1F, etc. in one transfer. | ||
| 75 | memcpy(i2c_transfer_buffer + 1, pwm_buffer + i, 16); | ||
| 76 | |||
| 77 | #if IS31FL3746A_I2C_PERSISTENCE > 0 | ||
| 78 | for (uint8_t i = 0; i < IS31FL3746A_I2C_PERSISTENCE; i++) { | ||
| 79 | if (i2c_transmit(addr << 1, i2c_transfer_buffer, 17, IS31FL3746A_I2C_TIMEOUT) != 0) break; | ||
| 80 | } | ||
| 81 | #else | ||
| 82 | i2c_transmit(addr << 1, i2c_transfer_buffer, 17, IS31FL3746A_I2C_TIMEOUT); | ||
| 83 | #endif | ||
| 84 | } | ||
| 85 | } | ||
| 86 | |||
| 87 | void is31fl3746a_init_drivers(void) { | ||
| 88 | i2c_init(); | ||
| 89 | |||
| 90 | is31fl3746a_init(IS31FL3746A_I2C_ADDRESS_1); | ||
| 91 | #if defined(IS31FL3746A_I2C_ADDRESS_2) | ||
| 92 | is31fl3746a_init(IS31FL3746A_I2C_ADDRESS_2); | ||
| 93 | # if defined(IS31FL3746A_I2C_ADDRESS_3) | ||
| 94 | is31fl3746a_init(IS31FL3746A_I2C_ADDRESS_3); | ||
| 95 | # if defined(IS31FL3746A_I2C_ADDRESS_4) | ||
| 96 | is31fl3746a_init(IS31FL3746A_I2C_ADDRESS_4); | ||
| 97 | # endif | ||
| 98 | # endif | ||
| 99 | #endif | ||
| 100 | |||
| 101 | for (int i = 0; i < IS31FL3746A_LED_COUNT; i++) { | ||
| 102 | is31fl3746a_set_scaling_register(i, 0xFF); | ||
| 103 | } | ||
| 104 | |||
| 105 | is31fl3746a_update_scaling_registers(IS31FL3746A_I2C_ADDRESS_1, 0); | ||
| 106 | #if defined(IS31FL3746A_I2C_ADDRESS_2) | ||
| 107 | is31fl3746a_update_scaling_registers(IS31FL3746A_I2C_ADDRESS_2, 1); | ||
| 108 | # if defined(IS31FL3746A_I2C_ADDRESS_3) | ||
| 109 | is31fl3746a_update_scaling_registers(IS31FL3746A_I2C_ADDRESS_3, 2); | ||
| 110 | # if defined(IS31FL3746A_I2C_ADDRESS_4) | ||
| 111 | is31fl3746a_update_scaling_registers(IS31FL3746A_I2C_ADDRESS_4, 3); | ||
| 112 | # endif | ||
| 113 | # endif | ||
| 114 | #endif | ||
| 115 | } | ||
| 116 | |||
| 117 | void is31fl3746a_init(uint8_t addr) { | ||
| 118 | // In order to avoid the LEDs being driven with garbage data | ||
| 119 | // in the LED driver's PWM registers, shutdown is enabled last. | ||
| 120 | // Set up the mode and other settings, clear the PWM registers, | ||
| 121 | // then disable software shutdown. | ||
| 122 | |||
| 123 | is31fl3746a_select_page(addr, IS31FL3746A_COMMAND_SCALING); | ||
| 124 | |||
| 125 | // Turn off all LEDs. | ||
| 126 | for (int i = 0; i < IS31FL3746A_SCALING_REGISTER_COUNT; i++) { | ||
| 127 | is31fl3746a_write_register(addr, i + 1, 0x00); | ||
| 128 | } | ||
| 129 | |||
| 130 | is31fl3746a_select_page(addr, IS31FL3746A_COMMAND_PWM); | ||
| 131 | |||
| 132 | for (int i = 0; i < IS31FL3746A_PWM_REGISTER_COUNT; i++) { | ||
| 133 | is31fl3746a_write_register(addr, i + 1, 0x00); | ||
| 134 | } | ||
| 135 | |||
| 136 | is31fl3746a_select_page(addr, IS31FL3746A_COMMAND_FUNCTION); | ||
| 137 | |||
| 138 | is31fl3746a_write_register(addr, IS31FL3746A_FUNCTION_REG_PULLDOWNUP, (IS31FL3746A_SW_PULLDOWN << 4) | IS31FL3746A_CS_PULLUP); | ||
| 139 | is31fl3746a_write_register(addr, IS31FL3746A_FUNCTION_REG_GLOBAL_CURRENT, IS31FL3746A_GLOBAL_CURRENT); | ||
| 140 | is31fl3746a_write_register(addr, IS31FL3746A_FUNCTION_REG_PWM_ENABLE, 0x01); | ||
| 141 | is31fl3746a_write_register(addr, IS31FL3746A_FUNCTION_REG_PWM_FREQUENCY, IS31FL3746A_PWM_FREQUENCY); | ||
| 142 | is31fl3746a_write_register(addr, IS31FL3746A_FUNCTION_REG_CONFIGURATION, IS31FL3746A_CONFIGURATION); | ||
| 143 | |||
| 144 | // Wait 10ms to ensure the device has woken up. | ||
| 145 | wait_ms(10); | ||
| 146 | } | ||
| 147 | |||
| 148 | void is31fl3746a_set_color(int index, uint8_t value) { | ||
| 149 | is31fl3746a_led_t led; | ||
| 150 | if (index >= 0 && index < IS31FL3746A_LED_COUNT) { | ||
| 151 | memcpy_P(&led, (&g_is31fl3746a_leds[index]), sizeof(led)); | ||
| 152 | |||
| 153 | if (g_pwm_buffer[led.driver][led.v] == value) { | ||
| 154 | return; | ||
| 155 | } | ||
| 156 | g_pwm_buffer_update_required[led.driver] = true; | ||
| 157 | g_pwm_buffer[led.driver][led.v] = value; | ||
| 158 | } | ||
| 159 | } | ||
| 160 | |||
| 161 | void is31fl3746a_set_value_all(uint8_t value) { | ||
| 162 | for (int i = 0; i < IS31FL3746A_LED_COUNT; i++) { | ||
| 163 | is31fl3746a_set_value(i, value); | ||
| 164 | } | ||
| 165 | } | ||
| 166 | |||
| 167 | void is31fl3746a_set_scaling_register(uint8_t index, uint8_t value) { | ||
| 168 | is31fl3746a_led_t led; | ||
| 169 | memcpy_P(&led, (&g_is31fl3746a_leds[index]), sizeof(led)); | ||
| 170 | |||
| 171 | g_scaling_registers[led.driver][led.v] = value; | ||
| 172 | |||
| 173 | g_scaling_registers_update_required[led.driver] = true; | ||
| 174 | } | ||
| 175 | |||
| 176 | void is31fl3746a_update_pwm_buffers(uint8_t addr, uint8_t index) { | ||
| 177 | if (g_pwm_buffer_update_required[index]) { | ||
| 178 | is31fl3746a_select_page(addr, IS31FL3746A_COMMAND_PWM); | ||
| 179 | |||
| 180 | is31fl3746a_write_pwm_buffer(addr, g_pwm_buffer[index]); | ||
| 181 | } | ||
| 182 | |||
| 183 | g_pwm_buffer_update_required[index] = false; | ||
| 184 | } | ||
| 185 | |||
| 186 | void is31fl3746a_update_scaling_registers(uint8_t addr, uint8_t index) { | ||
| 187 | if (g_scaling_registers_update_required[index]) { | ||
| 188 | is31fl3746a_select_page(addr, IS31FL3746A_COMMAND_SCALING); | ||
| 189 | |||
| 190 | for (int i = 0; i < IS31FL3746A_SCALING_REGISTER_COUNT; i++) { | ||
| 191 | is31fl3746a_write_register(addr, i + 1, g_scaling_registers[index][i]); | ||
| 192 | } | ||
| 193 | g_scaling_registers_update_required[index] = false; | ||
| 194 | } | ||
| 195 | } | ||
| 196 | |||
| 197 | void is31fl3746a_flush(void) { | ||
| 198 | is31fl3746a_update_pwm_buffers(IS31FL3746A_I2C_ADDRESS_1, 0); | ||
| 199 | #if defined(IS31FL3746A_I2C_ADDRESS_2) | ||
| 200 | is31fl3746a_update_pwm_buffers(IS31FL3746A_I2C_ADDRESS_2, 1); | ||
| 201 | # if defined(IS31FL3746A_I2C_ADDRESS_3) | ||
| 202 | is31fl3746a_update_pwm_buffers(IS31FL3746A_I2C_ADDRESS_3, 2); | ||
| 203 | # if defined(IS31FL3746A_I2C_ADDRESS_4) | ||
| 204 | is31fl3746a_update_pwm_buffers(IS31FL3746A_I2C_ADDRESS_4, 3); | ||
| 205 | # endif | ||
| 206 | # endif | ||
| 207 | #endif | ||
| 208 | } | ||
diff --git a/drivers/led/issi/is31fl3746a-simple.h b/drivers/led/issi/is31fl3746a-simple.h new file mode 100644 index 0000000000..eda644ad19 --- /dev/null +++ b/drivers/led/issi/is31fl3746a-simple.h | |||
| @@ -0,0 +1,192 @@ | |||
| 1 | /* Copyright 2017 Jason Williams | ||
| 2 | * Copyright 2018 Jack Humbert | ||
| 3 | * Copyright 2018 Yiancar | ||
| 4 | * Copyright 2020 MelGeek | ||
| 5 | * Copyright 2021 MasterSpoon | ||
| 6 | * | ||
| 7 | * This program is free software: you can redistribute it and/or modify | ||
| 8 | * it under the terms of the GNU General Public License as published by | ||
| 9 | * the Free Software Foundation, either version 2 of the License, or | ||
| 10 | * (at your option) any later version. | ||
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License | ||
| 18 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #pragma once | ||
| 22 | |||
| 23 | #include <stdint.h> | ||
| 24 | #include <stdbool.h> | ||
| 25 | #include "progmem.h" | ||
| 26 | #include "util.h" | ||
| 27 | |||
| 28 | #define IS31FL3746A_REG_ID 0xFC | ||
| 29 | |||
| 30 | #define IS31FL3746A_REG_COMMAND 0xFD | ||
| 31 | |||
| 32 | #define IS31FL3746A_COMMAND_PWM 0x00 | ||
| 33 | #define IS31FL3746A_COMMAND_SCALING 0x01 | ||
| 34 | #define IS31FL3746A_COMMAND_FUNCTION 0x01 | ||
| 35 | |||
| 36 | #define IS31FL3746A_FUNCTION_REG_CONFIGURATION 0x50 | ||
| 37 | #define IS31FL3746A_FUNCTION_REG_GLOBAL_CURRENT 0x51 | ||
| 38 | #define IS31FL3746A_FUNCTION_REG_PULLDOWNUP 0x52 | ||
| 39 | #define IS31FL3746A_FUNCTION_REG_TEMPERATURE 0x5F | ||
| 40 | #define IS31FL3746A_FUNCTION_REG_SPREAD_SPECTRUM 0x60 | ||
| 41 | #define IS31FL3746A_FUNCTION_REG_RESET 0x8F | ||
| 42 | #define IS31FL3746A_FUNCTION_REG_PWM_ENABLE 0xE0 | ||
| 43 | #define IS31FL3746A_FUNCTION_REG_PWM_FREQUENCY 0xE2 | ||
| 44 | |||
| 45 | #define IS31FL3746A_REG_COMMAND_WRITE_LOCK 0xFE | ||
| 46 | #define IS31FL3746A_COMMAND_WRITE_LOCK_MAGIC 0xC5 | ||
| 47 | |||
| 48 | #define IS31FL3746A_I2C_ADDRESS_GND_GND 0x60 | ||
| 49 | #define IS31FL3746A_I2C_ADDRESS_GND_SCL 0x61 | ||
| 50 | #define IS31FL3746A_I2C_ADDRESS_GND_SDA 0x62 | ||
| 51 | #define IS31FL3746A_I2C_ADDRESS_GND_VCC 0x63 | ||
| 52 | #define IS31FL3746A_I2C_ADDRESS_SCL_GND 0x64 | ||
| 53 | #define IS31FL3746A_I2C_ADDRESS_SCL_SCL 0x65 | ||
| 54 | #define IS31FL3746A_I2C_ADDRESS_SCL_SDA 0x66 | ||
| 55 | #define IS31FL3746A_I2C_ADDRESS_SCL_VCC 0x67 | ||
| 56 | #define IS31FL3746A_I2C_ADDRESS_SDA_GND 0x68 | ||
| 57 | #define IS31FL3746A_I2C_ADDRESS_SDA_SCL 0x69 | ||
| 58 | #define IS31FL3746A_I2C_ADDRESS_SDA_SDA 0x6A | ||
| 59 | #define IS31FL3746A_I2C_ADDRESS_SDA_VCC 0x6B | ||
| 60 | #define IS31FL3746A_I2C_ADDRESS_VCC_GND 0x6C | ||
| 61 | #define IS31FL3746A_I2C_ADDRESS_VCC_SCL 0x6D | ||
| 62 | #define IS31FL3746A_I2C_ADDRESS_VCC_SDA 0x6E | ||
| 63 | #define IS31FL3746A_I2C_ADDRESS_VCC_VCC 0x6F | ||
| 64 | |||
| 65 | #if defined(LED_MATRIX_IS31FL3746A) | ||
| 66 | # define IS31FL3746A_LED_COUNT LED_MATRIX_LED_COUNT | ||
| 67 | #endif | ||
| 68 | |||
| 69 | typedef struct is31fl3746a_led_t { | ||
| 70 | uint8_t driver : 2; | ||
| 71 | uint8_t v; | ||
| 72 | } PACKED is31fl3746a_led_t; | ||
| 73 | |||
| 74 | extern const is31fl3746a_led_t PROGMEM g_is31fl3746a_leds[IS31FL3746A_LED_COUNT]; | ||
| 75 | |||
| 76 | void is31fl3746a_init_drivers(void); | ||
| 77 | void is31fl3746a_init(uint8_t addr, uint8_t sync); | ||
| 78 | void is31fl3746a_write_register(uint8_t addr, uint8_t reg, uint8_t data); | ||
| 79 | void is31fl3746a_select_page(uint8_t addr, uint8_t page); | ||
| 80 | void is31fl3746a_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer); | ||
| 81 | |||
| 82 | void is31fl3746a_set_value(int index, uint8_t value); | ||
| 83 | void is31fl3746a_set_value_all(uint8_t value); | ||
| 84 | |||
| 85 | void is31fl3746a_set_scaling_register(uint8_t index, uint8_t value); | ||
| 86 | |||
| 87 | void is31fl3746a_update_pwm_buffers(uint8_t addr, uint8_t index); | ||
| 88 | void is31fl3746a_update_scaling_registers(uint8_t addr, uint8_t index); | ||
| 89 | |||
| 90 | void is31fl3746a_flush(void); | ||
| 91 | |||
| 92 | #define IS31FL3746A_PDR_0_OHM 0b000 // No pull-down resistor | ||
| 93 | #define IS31FL3746A_PDR_0K5_OHM_SW_OFF 0b001 // 0.5 kOhm resistor in SWx off time | ||
| 94 | #define IS31FL3746A_PDR_1K_OHM_SW_OFF 0b010 // 1 kOhm resistor in SWx off time | ||
| 95 | #define IS31FL3746A_PDR_2K_OHM_SW_OFF 0b011 // 2 kOhm resistor in SWx off time | ||
| 96 | #define IS31FL3746A_PDR_1K_OHM 0b100 // 1 kOhm resistor | ||
| 97 | #define IS31FL3746A_PDR_2K_OHM 0b101 // 2 kOhm resistor | ||
| 98 | #define IS31FL3746A_PDR_4K_OHM 0b110 // 4 kOhm resistor | ||
| 99 | #define IS31FL3746A_PDR_8K_OHM 0b111 // 8 kOhm resistor | ||
| 100 | |||
| 101 | #define IS31FL3746A_PUR_0_OHM 0b000 // No pull-up resistor | ||
| 102 | #define IS31FL3746A_PUR_0K5_OHM_CS_OFF 0b001 // 0.5 kOhm resistor in CSy off time | ||
| 103 | #define IS31FL3746A_PUR_1K_OHM_CS_OFF 0b010 // 1 kOhm resistor in CSy off time | ||
| 104 | #define IS31FL3746A_PUR_2K_OHM_CS_OFF 0b011 // 2 kOhm resistor in CSy off time | ||
| 105 | #define IS31FL3746A_PUR_1K_OHM 0b100 // 1 kOhm resistor | ||
| 106 | #define IS31FL3746A_PUR_2K_OHM 0b101 // 2 kOhm resistor | ||
| 107 | #define IS31FL3746A_PUR_4K_OHM 0b110 // 4 kOhm resistor | ||
| 108 | #define IS31FL3746A_PUR_8K_OHM 0b111 // 8 kOhm resistor | ||
| 109 | |||
| 110 | #define IS31FL3746A_PWM_FREQUENCY_29K_HZ 0b000 | ||
| 111 | #define IS31FL3746A_PWM_FREQUENCY_14K5_HZ 0b001 | ||
| 112 | #define IS31FL3746A_PWM_FREQUENCY_7K25_HZ 0b010 | ||
| 113 | #define IS31FL3746A_PWM_FREQUENCY_3K63_HZ 0b011 | ||
| 114 | #define IS31FL3746A_PWM_FREQUENCY_1K81_HZ 0b100 | ||
| 115 | #define IS31FL3746A_PWM_FREQUENCY_906_HZ 0b101 | ||
| 116 | #define IS31FL3746A_PWM_FREQUENCY_453_HZ 0b110 | ||
| 117 | |||
| 118 | #define CS1_SW1 0x00 | ||
| 119 | #define CS2_SW1 0x01 | ||
| 120 | #define CS3_SW1 0x02 | ||
| 121 | #define CS4_SW1 0x03 | ||
| 122 | #define CS5_SW1 0x04 | ||
| 123 | #define CS6_SW1 0x05 | ||
| 124 | #define CS7_SW1 0x06 | ||
| 125 | #define CS8_SW1 0x07 | ||
| 126 | #define CS9_SW1 0x08 | ||
| 127 | #define CS10_SW1 0x09 | ||
| 128 | #define CS11_SW1 0x0A | ||
| 129 | #define CS12_SW1 0x0B | ||
| 130 | #define CS13_SW1 0x0C | ||
| 131 | #define CS14_SW1 0x0D | ||
| 132 | #define CS15_SW1 0x0E | ||
| 133 | #define CS16_SW1 0x0F | ||
| 134 | #define CS17_SW1 0x10 | ||
| 135 | #define CS18_SW1 0x11 | ||
| 136 | |||
| 137 | #define CS1_SW2 0x12 | ||
| 138 | #define CS2_SW2 0x13 | ||
| 139 | #define CS3_SW2 0x14 | ||
| 140 | #define CS4_SW2 0x15 | ||
| 141 | #define CS5_SW2 0x16 | ||
| 142 | #define CS6_SW2 0x17 | ||
| 143 | #define CS7_SW2 0x18 | ||
| 144 | #define CS8_SW2 0x19 | ||
| 145 | #define CS9_SW2 0x1A | ||
| 146 | #define CS10_SW2 0x1B | ||
| 147 | #define CS11_SW2 0x1C | ||
| 148 | #define CS12_SW2 0x1D | ||
| 149 | #define CS13_SW2 0x1E | ||
| 150 | #define CS14_SW2 0x1F | ||
| 151 | #define CS15_SW2 0x20 | ||
| 152 | #define CS16_SW2 0x21 | ||
| 153 | #define CS17_SW2 0x22 | ||
| 154 | #define CS18_SW2 0x23 | ||
| 155 | |||
| 156 | #define CS1_SW3 0x24 | ||
| 157 | #define CS2_SW3 0x25 | ||
| 158 | #define CS3_SW3 0x26 | ||
| 159 | #define CS4_SW3 0x27 | ||
| 160 | #define CS5_SW3 0x28 | ||
| 161 | #define CS6_SW3 0x29 | ||
| 162 | #define CS7_SW3 0x2A | ||
| 163 | #define CS8_SW3 0x2B | ||
| 164 | #define CS9_SW3 0x2C | ||
| 165 | #define CS10_SW3 0x2D | ||
| 166 | #define CS11_SW3 0x2E | ||
| 167 | #define CS12_SW3 0x2F | ||
| 168 | #define CS13_SW3 0x30 | ||
| 169 | #define CS14_SW3 0x31 | ||
| 170 | #define CS15_SW3 0x32 | ||
| 171 | #define CS16_SW3 0x33 | ||
| 172 | #define CS17_SW3 0x34 | ||
| 173 | #define CS18_SW3 0x35 | ||
| 174 | |||
| 175 | #define CS1_SW4 0x36 | ||
| 176 | #define CS2_SW4 0x37 | ||
| 177 | #define CS3_SW4 0x38 | ||
| 178 | #define CS4_SW4 0x39 | ||
| 179 | #define CS5_SW4 0x3A | ||
| 180 | #define CS6_SW4 0x3B | ||
| 181 | #define CS7_SW4 0x3C | ||
| 182 | #define CS8_SW4 0x3D | ||
| 183 | #define CS9_SW4 0x3E | ||
| 184 | #define CS10_SW4 0x3F | ||
| 185 | #define CS11_SW4 0x40 | ||
| 186 | #define CS12_SW4 0x41 | ||
| 187 | #define CS13_SW4 0x42 | ||
| 188 | #define CS14_SW4 0x43 | ||
| 189 | #define CS15_SW4 0x44 | ||
| 190 | #define CS16_SW4 0x45 | ||
| 191 | #define CS17_SW4 0x46 | ||
| 192 | #define CS18_SW4 0x47 | ||
diff --git a/drivers/led/issi/is31fl3746a.c b/drivers/led/issi/is31fl3746a.c new file mode 100644 index 0000000000..5a3001f02f --- /dev/null +++ b/drivers/led/issi/is31fl3746a.c | |||
| @@ -0,0 +1,212 @@ | |||
| 1 | #include "is31fl3746a.h" | ||
| 2 | #include <string.h> | ||
| 3 | #include "i2c_master.h" | ||
| 4 | #include "wait.h" | ||
| 5 | |||
| 6 | #define IS31FL3746A_PWM_REGISTER_COUNT 72 | ||
| 7 | #define IS31FL3746A_SCALING_REGISTER_COUNT 72 | ||
| 8 | |||
| 9 | #ifndef IS31FL3746A_I2C_TIMEOUT | ||
| 10 | # define IS31FL3746A_I2C_TIMEOUT 100 | ||
| 11 | #endif | ||
| 12 | |||
| 13 | #ifndef IS31FL3746A_I2C_PERSISTENCE | ||
| 14 | # define IS31FL3746A_I2C_PERSISTENCE 0 | ||
| 15 | #endif | ||
| 16 | |||
| 17 | #ifndef IS31FL3746A_CONFIGURATION | ||
| 18 | # define IS31FL3746A_CONFIGURATION 0x01 | ||
| 19 | #endif | ||
| 20 | |||
| 21 | #ifndef IS31FL3746A_PWM_FREQUENCY | ||
| 22 | # define IS31FL3746A_PWM_FREQUENCY IS31FL3746A_PWM_FREQUENCY_29K_HZ | ||
| 23 | #endif | ||
| 24 | |||
| 25 | #ifndef IS31FL3746A_SW_PULLDOWN | ||
| 26 | # define IS31FL3746A_SW_PULLDOWN IS31FL3746A_PDR_2K_OHM_SW_OFF | ||
| 27 | #endif | ||
| 28 | |||
| 29 | #ifndef IS31FL3746A_CS_PULLUP | ||
| 30 | # define IS31FL3746A_CS_PULLUP IS31FL3746A_PUR_2K_OHM_CS_OFF | ||
| 31 | #endif | ||
| 32 | |||
| 33 | #ifndef IS31FL3746A_GLOBAL_CURRENT | ||
| 34 | # define IS31FL3746A_GLOBAL_CURRENT 0xFF | ||
| 35 | #endif | ||
| 36 | |||
| 37 | uint8_t i2c_transfer_buffer[20] = {0xFF}; | ||
| 38 | |||
| 39 | uint8_t g_pwm_buffer[IS31FL3746A_DRIVER_COUNT][IS31FL3746A_PWM_REGISTER_COUNT]; | ||
| 40 | bool g_pwm_buffer_update_required[IS31FL3746A_DRIVER_COUNT] = {false}; | ||
| 41 | bool g_scaling_registers_update_required[IS31FL3746A_DRIVER_COUNT] = {false}; | ||
| 42 | |||
| 43 | uint8_t g_scaling_registers[IS31FL3746A_DRIVER_COUNT][IS31FL3746A_SCALING_REGISTER_COUNT]; | ||
| 44 | |||
| 45 | void is31fl3746a_write_register(uint8_t addr, uint8_t reg, uint8_t data) { | ||
| 46 | i2c_transfer_buffer[0] = reg; | ||
| 47 | i2c_transfer_buffer[1] = data; | ||
| 48 | |||
| 49 | #if IS31FL3746A_I2C_PERSISTENCE > 0 | ||
| 50 | for (uint8_t i = 0; i < IS31FL3746A_I2C_PERSISTENCE; i++) { | ||
| 51 | if (i2c_transmit(addr << 1, i2c_transfer_buffer, 2, IS31FL3746A_I2C_TIMEOUT) == 0) break; | ||
| 52 | } | ||
| 53 | #else | ||
| 54 | i2c_transmit(addr << 1, i2c_transfer_buffer, 2, IS31FL3746A_I2C_TIMEOUT); | ||
| 55 | #endif | ||
| 56 | } | ||
| 57 | |||
| 58 | void is31fl3746a_select_page(uint8_t addr, uint8_t page) { | ||
| 59 | is31fl3746a_write_register(addr, IS31FL3746A_REG_COMMAND_WRITE_LOCK, IS31FL3746A_COMMAND_WRITE_LOCK_MAGIC); | ||
| 60 | is31fl3746a_write_register(addr, IS31FL3746A_REG_COMMAND, page); | ||
| 61 | } | ||
| 62 | |||
| 63 | void is31fl3746a_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer) { | ||
| 64 | // Assumes page 0 is already selected. | ||
| 65 | // If any of the transactions fails function returns false. | ||
| 66 | // Transmit PWM registers in 12 transfers of 16 bytes. | ||
| 67 | // i2c_transfer_buffer[] is 20 bytes | ||
| 68 | |||
| 69 | // Iterate over the pwm_buffer contents at 16 byte intervals. | ||
| 70 | for (int i = 0; i < IS31FL3746A_PWM_REGISTER_COUNT; i += 16) { | ||
| 71 | i2c_transfer_buffer[0] = i + 1; | ||
| 72 | // Copy the data from i to i+15. | ||
| 73 | // Device will auto-increment register for data after the first byte | ||
| 74 | // Thus this sets registers 0x00-0x0F, 0x10-0x1F, etc. in one transfer. | ||
| 75 | memcpy(i2c_transfer_buffer + 1, pwm_buffer + i, 16); | ||
| 76 | |||
| 77 | #if IS31FL3746A_I2C_PERSISTENCE > 0 | ||
| 78 | for (uint8_t i = 0; i < IS31FL3746A_I2C_PERSISTENCE; i++) { | ||
| 79 | if (i2c_transmit(addr << 1, i2c_transfer_buffer, 17, IS31FL3746A_I2C_TIMEOUT) != 0) break; | ||
| 80 | } | ||
| 81 | #else | ||
| 82 | i2c_transmit(addr << 1, i2c_transfer_buffer, 17, IS31FL3746A_I2C_TIMEOUT); | ||
| 83 | #endif | ||
| 84 | } | ||
| 85 | } | ||
| 86 | |||
| 87 | void is31fl3746a_init_drivers(void) { | ||
| 88 | i2c_init(); | ||
| 89 | |||
| 90 | is31fl3746a_init(IS31FL3746A_I2C_ADDRESS_1); | ||
| 91 | #if defined(IS31FL3746A_I2C_ADDRESS_2) | ||
| 92 | is31fl3746a_init(IS31FL3746A_I2C_ADDRESS_2); | ||
| 93 | # if defined(IS31FL3746A_I2C_ADDRESS_3) | ||
| 94 | is31fl3746a_init(IS31FL3746A_I2C_ADDRESS_3); | ||
| 95 | # if defined(IS31FL3746A_I2C_ADDRESS_4) | ||
| 96 | is31fl3746a_init(IS31FL3746A_I2C_ADDRESS_4); | ||
| 97 | # endif | ||
| 98 | # endif | ||
| 99 | #endif | ||
| 100 | |||
| 101 | for (int i = 0; i < IS31FL3746A_LED_COUNT; i++) { | ||
| 102 | is31fl3746a_set_scaling_register(i, 0xFF, 0xFF, 0xFF); | ||
| 103 | } | ||
| 104 | |||
| 105 | is31fl3746a_update_scaling_registers(IS31FL3746A_I2C_ADDRESS_1, 0); | ||
| 106 | #if defined(IS31FL3746A_I2C_ADDRESS_2) | ||
| 107 | is31fl3746a_update_scaling_registers(IS31FL3746A_I2C_ADDRESS_2, 1); | ||
| 108 | # if defined(IS31FL3746A_I2C_ADDRESS_3) | ||
| 109 | is31fl3746a_update_scaling_registers(IS31FL3746A_I2C_ADDRESS_3, 2); | ||
| 110 | # if defined(IS31FL3746A_I2C_ADDRESS_4) | ||
| 111 | is31fl3746a_update_scaling_registers(IS31FL3746A_I2C_ADDRESS_4, 3); | ||
| 112 | # endif | ||
| 113 | # endif | ||
| 114 | #endif | ||
| 115 | } | ||
| 116 | |||
| 117 | void is31fl3746a_init(uint8_t addr) { | ||
| 118 | // In order to avoid the LEDs being driven with garbage data | ||
| 119 | // in the LED driver's PWM registers, shutdown is enabled last. | ||
| 120 | // Set up the mode and other settings, clear the PWM registers, | ||
| 121 | // then disable software shutdown. | ||
| 122 | |||
| 123 | is31fl3746a_select_page(addr, IS31FL3746A_COMMAND_SCALING); | ||
| 124 | |||
| 125 | // Turn off all LEDs. | ||
| 126 | for (int i = 0; i < IS31FL3746A_SCALING_REGISTER_COUNT; i++) { | ||
| 127 | is31fl3746a_write_register(addr, i + 1, 0x00); | ||
| 128 | } | ||
| 129 | |||
| 130 | is31fl3746a_select_page(addr, IS31FL3746A_COMMAND_PWM); | ||
| 131 | |||
| 132 | for (int i = 0; i < IS31FL3746A_PWM_REGISTER_COUNT; i++) { | ||
| 133 | is31fl3746a_write_register(addr, i + 1, 0x00); | ||
| 134 | } | ||
| 135 | |||
| 136 | is31fl3746a_select_page(addr, IS31FL3746A_COMMAND_FUNCTION); | ||
| 137 | |||
| 138 | is31fl3746a_write_register(addr, IS31FL3746A_FUNCTION_REG_PULLDOWNUP, (IS31FL3746A_SW_PULLDOWN << 4) | IS31FL3746A_CS_PULLUP); | ||
| 139 | is31fl3746a_write_register(addr, IS31FL3746A_FUNCTION_REG_GLOBAL_CURRENT, IS31FL3746A_GLOBAL_CURRENT); | ||
| 140 | is31fl3746a_write_register(addr, IS31FL3746A_FUNCTION_REG_PWM_ENABLE, 0x01); | ||
| 141 | is31fl3746a_write_register(addr, IS31FL3746A_FUNCTION_REG_PWM_FREQUENCY, IS31FL3746A_PWM_FREQUENCY); | ||
| 142 | is31fl3746a_write_register(addr, IS31FL3746A_FUNCTION_REG_CONFIGURATION, IS31FL3746A_CONFIGURATION); | ||
| 143 | |||
| 144 | // Wait 10ms to ensure the device has woken up. | ||
| 145 | wait_ms(10); | ||
| 146 | } | ||
| 147 | |||
| 148 | void is31fl3746a_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { | ||
| 149 | is31fl3746a_led_t led; | ||
| 150 | if (index >= 0 && index < IS31FL3746A_LED_COUNT) { | ||
| 151 | memcpy_P(&led, (&g_is31fl3746a_leds[index]), sizeof(led)); | ||
| 152 | |||
| 153 | if (g_pwm_buffer[led.driver][led.r] == red && g_pwm_buffer[led.driver][led.g] == green && g_pwm_buffer[led.driver][led.b] == blue) { | ||
| 154 | return; | ||
| 155 | } | ||
| 156 | g_pwm_buffer_update_required[led.driver] = true; | ||
| 157 | g_pwm_buffer[led.driver][led.r] = red; | ||
| 158 | g_pwm_buffer[led.driver][led.g] = green; | ||
| 159 | g_pwm_buffer[led.driver][led.b] = blue; | ||
| 160 | } | ||
| 161 | } | ||
| 162 | |||
| 163 | void is31fl3746a_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { | ||
| 164 | for (int i = 0; i < IS31FL3746A_LED_COUNT; i++) { | ||
| 165 | is31fl3746a_set_color(i, red, green, blue); | ||
| 166 | } | ||
| 167 | } | ||
| 168 | |||
| 169 | void is31fl3746a_set_scaling_register(uint8_t index, uint8_t red, uint8_t green, uint8_t blue) { | ||
| 170 | is31fl3746a_led_t led; | ||
| 171 | memcpy_P(&led, (&g_is31fl3746a_leds[index]), sizeof(led)); | ||
| 172 | |||
| 173 | g_scaling_registers[led.driver][led.r] = red; | ||
| 174 | g_scaling_registers[led.driver][led.g] = green; | ||
| 175 | g_scaling_registers[led.driver][led.b] = blue; | ||
| 176 | |||
| 177 | g_scaling_registers_update_required[led.driver] = true; | ||
| 178 | } | ||
| 179 | |||
| 180 | void is31fl3746a_update_pwm_buffers(uint8_t addr, uint8_t index) { | ||
| 181 | if (g_pwm_buffer_update_required[index]) { | ||
| 182 | is31fl3746a_select_page(addr, IS31FL3746A_COMMAND_PWM); | ||
| 183 | |||
| 184 | is31fl3746a_write_pwm_buffer(addr, g_pwm_buffer[index]); | ||
| 185 | } | ||
| 186 | |||
| 187 | g_pwm_buffer_update_required[index] = false; | ||
| 188 | } | ||
| 189 | |||
| 190 | void is31fl3746a_update_scaling_registers(uint8_t addr, uint8_t index) { | ||
| 191 | if (g_scaling_registers_update_required[index]) { | ||
| 192 | is31fl3746a_select_page(addr, IS31FL3746A_COMMAND_SCALING); | ||
| 193 | |||
| 194 | for (int i = 0; i < IS31FL3746A_SCALING_REGISTER_COUNT; i++) { | ||
| 195 | is31fl3746a_write_register(addr, i + 1, g_scaling_registers[index][i]); | ||
| 196 | } | ||
| 197 | g_scaling_registers_update_required[index] = false; | ||
| 198 | } | ||
| 199 | } | ||
| 200 | |||
| 201 | void is31fl3746a_flush(void) { | ||
| 202 | is31fl3746a_update_pwm_buffers(IS31FL3746A_I2C_ADDRESS_1, 0); | ||
| 203 | #if defined(IS31FL3746A_I2C_ADDRESS_2) | ||
| 204 | is31fl3746a_update_pwm_buffers(IS31FL3746A_I2C_ADDRESS_2, 1); | ||
| 205 | # if defined(IS31FL3746A_I2C_ADDRESS_3) | ||
| 206 | is31fl3746a_update_pwm_buffers(IS31FL3746A_I2C_ADDRESS_3, 2); | ||
| 207 | # if defined(IS31FL3746A_I2C_ADDRESS_4) | ||
| 208 | is31fl3746a_update_pwm_buffers(IS31FL3746A_I2C_ADDRESS_4, 3); | ||
| 209 | # endif | ||
| 210 | # endif | ||
| 211 | #endif | ||
| 212 | } | ||
diff --git a/drivers/led/issi/is31fl3746a.h b/drivers/led/issi/is31fl3746a.h new file mode 100644 index 0000000000..f335e98e82 --- /dev/null +++ b/drivers/led/issi/is31fl3746a.h | |||
| @@ -0,0 +1,194 @@ | |||
| 1 | /* Copyright 2017 Jason Williams | ||
| 2 | * Copyright 2018 Jack Humbert | ||
| 3 | * Copyright 2018 Yiancar | ||
| 4 | * Copyright 2020 MelGeek | ||
| 5 | * Copyright 2021 MasterSpoon | ||
| 6 | * | ||
| 7 | * This program is free software: you can redistribute it and/or modify | ||
| 8 | * it under the terms of the GNU General Public License as published by | ||
| 9 | * the Free Software Foundation, either version 2 of the License, or | ||
| 10 | * (at your option) any later version. | ||
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License | ||
| 18 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #pragma once | ||
| 22 | |||
| 23 | #include <stdint.h> | ||
| 24 | #include <stdbool.h> | ||
| 25 | #include "progmem.h" | ||
| 26 | #include "util.h" | ||
| 27 | |||
| 28 | #define IS31FL3746A_REG_ID 0xFC | ||
| 29 | |||
| 30 | #define IS31FL3746A_REG_COMMAND 0xFD | ||
| 31 | |||
| 32 | #define IS31FL3746A_COMMAND_PWM 0x00 | ||
| 33 | #define IS31FL3746A_COMMAND_SCALING 0x01 | ||
| 34 | #define IS31FL3746A_COMMAND_FUNCTION 0x01 | ||
| 35 | |||
| 36 | #define IS31FL3746A_FUNCTION_REG_CONFIGURATION 0x50 | ||
| 37 | #define IS31FL3746A_FUNCTION_REG_GLOBAL_CURRENT 0x51 | ||
| 38 | #define IS31FL3746A_FUNCTION_REG_PULLDOWNUP 0x52 | ||
| 39 | #define IS31FL3746A_FUNCTION_REG_TEMPERATURE 0x5F | ||
| 40 | #define IS31FL3746A_FUNCTION_REG_SPREAD_SPECTRUM 0x60 | ||
| 41 | #define IS31FL3746A_FUNCTION_REG_RESET 0x8F | ||
| 42 | #define IS31FL3746A_FUNCTION_REG_PWM_ENABLE 0xE0 | ||
| 43 | #define IS31FL3746A_FUNCTION_REG_PWM_FREQUENCY 0xE2 | ||
| 44 | |||
| 45 | #define IS31FL3746A_REG_COMMAND_WRITE_LOCK 0xFE | ||
| 46 | #define IS31FL3746A_COMMAND_WRITE_LOCK_MAGIC 0xC5 | ||
| 47 | |||
| 48 | #define IS31FL3746A_I2C_ADDRESS_GND_GND 0x60 | ||
| 49 | #define IS31FL3746A_I2C_ADDRESS_GND_SCL 0x61 | ||
| 50 | #define IS31FL3746A_I2C_ADDRESS_GND_SDA 0x62 | ||
| 51 | #define IS31FL3746A_I2C_ADDRESS_GND_VCC 0x63 | ||
| 52 | #define IS31FL3746A_I2C_ADDRESS_SCL_GND 0x64 | ||
| 53 | #define IS31FL3746A_I2C_ADDRESS_SCL_SCL 0x65 | ||
| 54 | #define IS31FL3746A_I2C_ADDRESS_SCL_SDA 0x66 | ||
| 55 | #define IS31FL3746A_I2C_ADDRESS_SCL_VCC 0x67 | ||
| 56 | #define IS31FL3746A_I2C_ADDRESS_SDA_GND 0x68 | ||
| 57 | #define IS31FL3746A_I2C_ADDRESS_SDA_SCL 0x69 | ||
| 58 | #define IS31FL3746A_I2C_ADDRESS_SDA_SDA 0x6A | ||
| 59 | #define IS31FL3746A_I2C_ADDRESS_SDA_VCC 0x6B | ||
| 60 | #define IS31FL3746A_I2C_ADDRESS_VCC_GND 0x6C | ||
| 61 | #define IS31FL3746A_I2C_ADDRESS_VCC_SCL 0x6D | ||
| 62 | #define IS31FL3746A_I2C_ADDRESS_VCC_SDA 0x6E | ||
| 63 | #define IS31FL3746A_I2C_ADDRESS_VCC_VCC 0x6F | ||
| 64 | |||
| 65 | #if defined(RGB_MATRIX_IS31FL3746A) | ||
| 66 | # define IS31FL3746A_LED_COUNT RGB_MATRIX_LED_COUNT | ||
| 67 | #endif | ||
| 68 | |||
| 69 | typedef struct is31fl3746a_led_t { | ||
| 70 | uint8_t driver : 2; | ||
| 71 | uint8_t r; | ||
| 72 | uint8_t g; | ||
| 73 | uint8_t b; | ||
| 74 | } PACKED is31fl3746a_led_t; | ||
| 75 | |||
| 76 | extern const is31fl3746a_led_t PROGMEM g_is31fl3746a_leds[IS31FL3746A_LED_COUNT]; | ||
| 77 | |||
| 78 | void is31fl3746a_init_drivers(void); | ||
| 79 | void is31fl3746a_init(uint8_t addr, uint8_t sync); | ||
| 80 | void is31fl3746a_write_register(uint8_t addr, uint8_t reg, uint8_t data); | ||
| 81 | void is31fl3746a_select_page(uint8_t addr, uint8_t page); | ||
| 82 | void is31fl3746a_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer); | ||
| 83 | |||
| 84 | void is31fl3746a_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); | ||
| 85 | void is31fl3746a_set_color_all(uint8_t red, uint8_t green, uint8_t blue); | ||
| 86 | |||
| 87 | void is31fl3746a_set_scaling_register(uint8_t index, uint8_t red, uint8_t green, uint8_t blue); | ||
| 88 | |||
| 89 | void is31fl3746a_update_pwm_buffers(uint8_t addr, uint8_t index); | ||
| 90 | void is31fl3746a_update_scaling_registers(uint8_t addr, uint8_t index); | ||
| 91 | |||
| 92 | void is31fl3746a_flush(void); | ||
| 93 | |||
| 94 | #define IS31FL3746A_PDR_0_OHM 0b000 // No pull-down resistor | ||
| 95 | #define IS31FL3746A_PDR_0K5_OHM_SW_OFF 0b001 // 0.5 kOhm resistor in SWx off time | ||
| 96 | #define IS31FL3746A_PDR_1K_OHM_SW_OFF 0b010 // 1 kOhm resistor in SWx off time | ||
| 97 | #define IS31FL3746A_PDR_2K_OHM_SW_OFF 0b011 // 2 kOhm resistor in SWx off time | ||
| 98 | #define IS31FL3746A_PDR_1K_OHM 0b100 // 1 kOhm resistor | ||
| 99 | #define IS31FL3746A_PDR_2K_OHM 0b101 // 2 kOhm resistor | ||
| 100 | #define IS31FL3746A_PDR_4K_OHM 0b110 // 4 kOhm resistor | ||
| 101 | #define IS31FL3746A_PDR_8K_OHM 0b111 // 8 kOhm resistor | ||
| 102 | |||
| 103 | #define IS31FL3746A_PUR_0_OHM 0b000 // No pull-up resistor | ||
| 104 | #define IS31FL3746A_PUR_0K5_OHM_CS_OFF 0b001 // 0.5 kOhm resistor in CSy off time | ||
| 105 | #define IS31FL3746A_PUR_1K_OHM_CS_OFF 0b010 // 1 kOhm resistor in CSy off time | ||
| 106 | #define IS31FL3746A_PUR_2K_OHM_CS_OFF 0b011 // 2 kOhm resistor in CSy off time | ||
| 107 | #define IS31FL3746A_PUR_1K_OHM 0b100 // 1 kOhm resistor | ||
| 108 | #define IS31FL3746A_PUR_2K_OHM 0b101 // 2 kOhm resistor | ||
| 109 | #define IS31FL3746A_PUR_4K_OHM 0b110 // 4 kOhm resistor | ||
| 110 | #define IS31FL3746A_PUR_8K_OHM 0b111 // 8 kOhm resistor | ||
| 111 | |||
| 112 | #define IS31FL3746A_PWM_FREQUENCY_29K_HZ 0b000 | ||
| 113 | #define IS31FL3746A_PWM_FREQUENCY_14K5_HZ 0b001 | ||
| 114 | #define IS31FL3746A_PWM_FREQUENCY_7K25_HZ 0b010 | ||
| 115 | #define IS31FL3746A_PWM_FREQUENCY_3K63_HZ 0b011 | ||
| 116 | #define IS31FL3746A_PWM_FREQUENCY_1K81_HZ 0b100 | ||
| 117 | #define IS31FL3746A_PWM_FREQUENCY_906_HZ 0b101 | ||
| 118 | #define IS31FL3746A_PWM_FREQUENCY_453_HZ 0b110 | ||
| 119 | |||
| 120 | #define CS1_SW1 0x00 | ||
| 121 | #define CS2_SW1 0x01 | ||
| 122 | #define CS3_SW1 0x02 | ||
| 123 | #define CS4_SW1 0x03 | ||
| 124 | #define CS5_SW1 0x04 | ||
| 125 | #define CS6_SW1 0x05 | ||
| 126 | #define CS7_SW1 0x06 | ||
| 127 | #define CS8_SW1 0x07 | ||
| 128 | #define CS9_SW1 0x08 | ||
| 129 | #define CS10_SW1 0x09 | ||
| 130 | #define CS11_SW1 0x0A | ||
| 131 | #define CS12_SW1 0x0B | ||
| 132 | #define CS13_SW1 0x0C | ||
| 133 | #define CS14_SW1 0x0D | ||
| 134 | #define CS15_SW1 0x0E | ||
| 135 | #define CS16_SW1 0x0F | ||
| 136 | #define CS17_SW1 0x10 | ||
| 137 | #define CS18_SW1 0x11 | ||
| 138 | |||
| 139 | #define CS1_SW2 0x12 | ||
| 140 | #define CS2_SW2 0x13 | ||
| 141 | #define CS3_SW2 0x14 | ||
| 142 | #define CS4_SW2 0x15 | ||
| 143 | #define CS5_SW2 0x16 | ||
| 144 | #define CS6_SW2 0x17 | ||
| 145 | #define CS7_SW2 0x18 | ||
| 146 | #define CS8_SW2 0x19 | ||
| 147 | #define CS9_SW2 0x1A | ||
| 148 | #define CS10_SW2 0x1B | ||
| 149 | #define CS11_SW2 0x1C | ||
| 150 | #define CS12_SW2 0x1D | ||
| 151 | #define CS13_SW2 0x1E | ||
| 152 | #define CS14_SW2 0x1F | ||
| 153 | #define CS15_SW2 0x20 | ||
| 154 | #define CS16_SW2 0x21 | ||
| 155 | #define CS17_SW2 0x22 | ||
| 156 | #define CS18_SW2 0x23 | ||
| 157 | |||
| 158 | #define CS1_SW3 0x24 | ||
| 159 | #define CS2_SW3 0x25 | ||
| 160 | #define CS3_SW3 0x26 | ||
| 161 | #define CS4_SW3 0x27 | ||
| 162 | #define CS5_SW3 0x28 | ||
| 163 | #define CS6_SW3 0x29 | ||
| 164 | #define CS7_SW3 0x2A | ||
| 165 | #define CS8_SW3 0x2B | ||
| 166 | #define CS9_SW3 0x2C | ||
| 167 | #define CS10_SW3 0x2D | ||
| 168 | #define CS11_SW3 0x2E | ||
| 169 | #define CS12_SW3 0x2F | ||
| 170 | #define CS13_SW3 0x30 | ||
| 171 | #define CS14_SW3 0x31 | ||
| 172 | #define CS15_SW3 0x32 | ||
| 173 | #define CS16_SW3 0x33 | ||
| 174 | #define CS17_SW3 0x34 | ||
| 175 | #define CS18_SW3 0x35 | ||
| 176 | |||
| 177 | #define CS1_SW4 0x36 | ||
| 178 | #define CS2_SW4 0x37 | ||
| 179 | #define CS3_SW4 0x38 | ||
| 180 | #define CS4_SW4 0x39 | ||
| 181 | #define CS5_SW4 0x3A | ||
| 182 | #define CS6_SW4 0x3B | ||
| 183 | #define CS7_SW4 0x3C | ||
| 184 | #define CS8_SW4 0x3D | ||
| 185 | #define CS9_SW4 0x3E | ||
| 186 | #define CS10_SW4 0x3F | ||
| 187 | #define CS11_SW4 0x40 | ||
| 188 | #define CS12_SW4 0x41 | ||
| 189 | #define CS13_SW4 0x42 | ||
| 190 | #define CS14_SW4 0x43 | ||
| 191 | #define CS15_SW4 0x44 | ||
| 192 | #define CS16_SW4 0x45 | ||
| 193 | #define CS17_SW4 0x46 | ||
| 194 | #define CS18_SW4 0x47 | ||
diff --git a/drivers/led/issi/is31flcommon.h b/drivers/led/issi/is31flcommon.h index e5c4c52125..db7cd24b48 100644 --- a/drivers/led/issi/is31flcommon.h +++ b/drivers/led/issi/is31flcommon.h | |||
| @@ -25,11 +25,6 @@ | |||
| 25 | #include "progmem.h" | 25 | #include "progmem.h" |
| 26 | #include "util.h" | 26 | #include "util.h" |
| 27 | 27 | ||
| 28 | // Which variant header file to use | ||
| 29 | #if defined(LED_MATRIX_IS31FL3746A) || defined(RGB_MATRIX_IS31FL3746A) | ||
| 30 | # include "is31fl3746.h" | ||
| 31 | #endif | ||
| 32 | |||
| 33 | #if defined DRIVER_ADDR_4 | 28 | #if defined DRIVER_ADDR_4 |
| 34 | # define DRIVER_COUNT 4 | 29 | # define DRIVER_COUNT 4 |
| 35 | #elif defined DRIVER_ADDR_3 | 30 | #elif defined DRIVER_ADDR_3 |
diff --git a/quantum/led_matrix/led_matrix_drivers.c b/quantum/led_matrix/led_matrix_drivers.c index f244ae30e9..73e2513a11 100644 --- a/quantum/led_matrix/led_matrix_drivers.c +++ b/quantum/led_matrix/led_matrix_drivers.c | |||
| @@ -97,6 +97,14 @@ const led_matrix_driver_t led_matrix_driver = { | |||
| 97 | .set_value_all = is31fl3745_set_value_all, | 97 | .set_value_all = is31fl3745_set_value_all, |
| 98 | }; | 98 | }; |
| 99 | 99 | ||
| 100 | #elif defined(LED_MATRIX_IS31FL3746A) | ||
| 101 | const led_matrix_driver_t led_matrix_driver = { | ||
| 102 | .init = is31fl3746a_init_drivers, | ||
| 103 | .flush = is31fl3746a_flush, | ||
| 104 | .set_value = is31fl3746a_set_value, | ||
| 105 | .set_value_all = is31fl3746a_set_value_all, | ||
| 106 | }; | ||
| 107 | |||
| 100 | #elif defined(IS31FLCOMMON) | 108 | #elif defined(IS31FLCOMMON) |
| 101 | const led_matrix_driver_t led_matrix_driver = { | 109 | const led_matrix_driver_t led_matrix_driver = { |
| 102 | .init = IS31FL_simple_init_drivers, | 110 | .init = IS31FL_simple_init_drivers, |
diff --git a/quantum/led_matrix/led_matrix_drivers.h b/quantum/led_matrix/led_matrix_drivers.h index 01821a83c4..4eab0ac748 100644 --- a/quantum/led_matrix/led_matrix_drivers.h +++ b/quantum/led_matrix/led_matrix_drivers.h | |||
| @@ -23,6 +23,8 @@ | |||
| 23 | # include "is31fl3743a-simple.h" | 23 | # include "is31fl3743a-simple.h" |
| 24 | #elif defined(LED_MATRIX_IS31FL3745) | 24 | #elif defined(LED_MATRIX_IS31FL3745) |
| 25 | # include "is31fl3745-simple.h" | 25 | # include "is31fl3745-simple.h" |
| 26 | #elif defined(LED_MATRIX_IS31FL3746A) | ||
| 27 | # include "is31fl3746a-simple.h" | ||
| 26 | #elif defined(IS31FLCOMMON) | 28 | #elif defined(IS31FLCOMMON) |
| 27 | # include "is31flcommon.h" | 29 | # include "is31flcommon.h" |
| 28 | #elif defined(LED_MATRIX_SNLED27351) | 30 | #elif defined(LED_MATRIX_SNLED27351) |
diff --git a/quantum/rgb_matrix/rgb_matrix_drivers.c b/quantum/rgb_matrix/rgb_matrix_drivers.c index 0a41991efb..e3dd9beff7 100644 --- a/quantum/rgb_matrix/rgb_matrix_drivers.c +++ b/quantum/rgb_matrix/rgb_matrix_drivers.c | |||
| @@ -100,6 +100,14 @@ const rgb_matrix_driver_t rgb_matrix_driver = { | |||
| 100 | .set_color_all = is31fl3745_set_color_all, | 100 | .set_color_all = is31fl3745_set_color_all, |
| 101 | }; | 101 | }; |
| 102 | 102 | ||
| 103 | #elif defined(RGB_MATRIX_IS31FL3746A) | ||
| 104 | const rgb_matrix_driver_t rgb_matrix_driver = { | ||
| 105 | .init = is31fl3746a_init_drivers, | ||
| 106 | .flush = is31fl3746a_flush, | ||
| 107 | .set_color = is31fl3746a_set_color, | ||
| 108 | .set_color_all = is31fl3746a_set_color_all, | ||
| 109 | }; | ||
| 110 | |||
| 103 | #elif defined(IS31FLCOMMON) | 111 | #elif defined(IS31FLCOMMON) |
| 104 | const rgb_matrix_driver_t rgb_matrix_driver = { | 112 | const rgb_matrix_driver_t rgb_matrix_driver = { |
| 105 | .init = IS31FL_RGB_init_drivers, | 113 | .init = IS31FL_RGB_init_drivers, |
diff --git a/quantum/rgb_matrix/rgb_matrix_drivers.h b/quantum/rgb_matrix/rgb_matrix_drivers.h index 786f2fa37a..07d376dfd7 100644 --- a/quantum/rgb_matrix/rgb_matrix_drivers.h +++ b/quantum/rgb_matrix/rgb_matrix_drivers.h | |||
| @@ -25,6 +25,8 @@ | |||
| 25 | # include "is31fl3743a.h" | 25 | # include "is31fl3743a.h" |
| 26 | #elif defined(RGB_MATRIX_IS31FL3745) | 26 | #elif defined(RGB_MATRIX_IS31FL3745) |
| 27 | # include "is31fl3745.h" | 27 | # include "is31fl3745.h" |
| 28 | #elif defined(RGB_MATRIX_IS31FL3746A) | ||
| 29 | # include "is31fl3746a.h" | ||
| 28 | #elif defined(IS31FLCOMMON) | 30 | #elif defined(IS31FLCOMMON) |
| 29 | # include "is31flcommon.h" | 31 | # include "is31flcommon.h" |
| 30 | #elif defined(RGB_MATRIX_SNLED27351) | 32 | #elif defined(RGB_MATRIX_SNLED27351) |
