From 53a15afb8f7ef322339c9864a1bf0b8e090f3e73 Mon Sep 17 00:00:00 2001 From: ccullin Date: Sun, 4 Jul 2021 15:53:46 +1000 Subject: [PATCH 1/5] initial commit --- docs/feature_rgb_matrix.md | 46 +++++------------------------ drivers/issi/is31fl3737.c | 57 +++++++++++++++++++++--------------- quantum/rgb_matrix_drivers.c | 16 ++++++++-- 3 files changed, 56 insertions(+), 63 deletions(-) diff --git a/docs/feature_rgb_matrix.md b/docs/feature_rgb_matrix.md index 08d5c9c4c6ae..11de4c888162 100644 --- a/docs/feature_rgb_matrix.md +++ b/docs/feature_rgb_matrix.md @@ -145,6 +145,7 @@ There is basic support for addressable RGB matrix lighting with the I2C IS31FL37 RGB_MATRIX_ENABLE = yes RGB_MATRIX_DRIVER = IS31FL3737 ``` +You can use between 1 and 2 IS31FL3737 IC's. Do not specify `DRIVER_ADDR_2` define for second IC if not present on your keyboard. Configure the hardware via your `config.h`: @@ -159,14 +160,16 @@ Configure the hardware via your `config.h`: // ADDR represents A3:A0 of the 7-bit address. // The result is: 0b101(ADDR) #define DRIVER_ADDR_1 0b1010000 -#define DRIVER_ADDR_2 0b1010000 // this is here for compliancy reasons. +#define DRIVER_ADDR_2 0b1010001 #define DRIVER_COUNT 2 -#define DRIVER_1_LED_TOTAL 64 -#define DRIVER_LED_TOTAL DRIVER_1_LED_TOTAL +#define DRIVER_1_LED_TOTAL 30 +#define DRIVER_2_LED_TOTAL 36 +#define DRIVER_LED_TOTAL (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL) ``` +!> Note the parentheses, this is so when `DRIVER_LED_TOTAL` is used in code and expanded, the values are added together before any additional math is applied to them. As an example, `rand() % (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)` will give very different results than `rand() % DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL`. -Currently only a single drivers is supported, but it would be trivial to support all 4 combinations. For now define `DRIVER_ADDR_2` as `DRIVER_ADDR_1` +Currently only two drivers are supported, but it would be trivial to support all 4 combinations. Define these arrays listing all the LEDs in your `.c`: @@ -183,7 +186,7 @@ const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { } ``` -Where `X_Y` is the location of the LED in the matrix defined by [the datasheet](https://www.issi.com/WW/pdf/31FL3737.pdf) and the header file `drivers/issi/is31fl3737.h`. The `driver` is the index of the driver you defined in your `config.h` (Only `0` right now). +Where `X_Y` is the location of the LED in the matrix defined by [the datasheet](https://www.issi.com/WW/pdf/31FL3737.pdf) and the header file `drivers/issi/is31fl3737.h`. The `driver` is the index of the driver you defined in your `config.h` (Only `0`, `1` for now). --- @@ -624,39 +627,6 @@ void rgb_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max) { } ``` -### Indicator Examples :id=indicator-examples - -Caps Lock indicator on alphanumeric flagged keys: -```c -void rgb_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max) { - if (host_keyboard_led_state().caps_lock) { - for (uint8_t i = led_min; i <= led_max; i++) { - if (g_led_config.flags[i] & LED_FLAG_KEYLIGHT) { - rgb_matrix_set_color(i, RGB_RED); - } - } - } -} -``` - -Layer indicator on all flagged keys: -```c -void rgb_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max) { - for (uint8_t i = led_min; i <= led_max; i++) { - switch(get_highest_layer(layer_state|default_layer_state)) { - case RAISE: - rgb_matrix_set_color(i, RGB_BLUE); - break; - case LOWER: - rgb_matrix_set_color(i, RGB_YELLOW); - break; - default: - break; - } - } -} -``` - ### Suspended state :id=suspended-state To use the suspend feature, make sure that `#define RGB_DISABLE_WHEN_USB_SUSPENDED true` is added to the `config.h` file. diff --git a/drivers/issi/is31fl3737.c b/drivers/issi/is31fl3737.c index 8647c93cc114..cdc3341a2950 100644 --- a/drivers/issi/is31fl3737.c +++ b/drivers/issi/is31fl3737.c @@ -19,6 +19,7 @@ #include "is31fl3737.h" #include "i2c_master.h" #include "wait.h" +#include "progmem.h" // This is a 7-bit address, that gets left-shifted and bit 0 // set to 0 for write, 1 for read (as per I2C protocol) @@ -65,11 +66,15 @@ uint8_t g_twi_transfer_buffer[20]; // We could optimize this and take out the unused registers from these // buffers and the transfers in IS31FL3737_write_pwm_buffer() but it's // probably not worth the extra complexity. -uint8_t g_pwm_buffer[DRIVER_COUNT][192]; -bool g_pwm_buffer_update_required = false; -uint8_t g_led_control_registers[DRIVER_COUNT][24] = {{0}}; -bool g_led_control_registers_update_required = false; + + + +uint8_t g_pwm_buffer[DRIVER_COUNT][(192)]; +bool g_pwm_buffer_update_required[DRIVER_COUNT] = {false}; + +uint8_t g_led_control_registers[DRIVER_COUNT][24] = {0}; +bool g_led_control_registers_update_required[DRIVER_COUNT] = {false}; void IS31FL3737_write_register(uint8_t addr, uint8_t reg, uint8_t data) { g_twi_transfer_buffer[0] = reg; @@ -84,7 +89,7 @@ void IS31FL3737_write_register(uint8_t addr, uint8_t reg, uint8_t data) { #endif } -void IS31FL3737_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer) { +bool IS31FL3737_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer) { // assumes PG1 is already selected // transmit PWM registers in 12 transfers of 16 bytes @@ -102,12 +107,17 @@ void IS31FL3737_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer) { #if ISSI_PERSISTENCE > 0 for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) { - if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT) == 0) break; + if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT) != 0) { + return false; + } } #else - i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT); + if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT) != 0) { + return false; + } #endif } + return true; } void IS31FL3737_init(uint8_t addr) { @@ -158,7 +168,7 @@ void IS31FL3737_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { g_pwm_buffer[led.driver][led.r] = red; g_pwm_buffer[led.driver][led.g] = green; g_pwm_buffer[led.driver][led.b] = blue; - g_pwm_buffer_update_required = true; + g_pwm_buffer_update_required[led.driver] = true; } } @@ -194,30 +204,31 @@ void IS31FL3737_set_led_control_register(uint8_t index, bool red, bool green, bo g_led_control_registers[led.driver][control_register_b] &= ~(1 << bit_b); } - g_led_control_registers_update_required = true; + g_led_control_registers_update_required[led.driver] = true; } -void IS31FL3737_update_pwm_buffers(uint8_t addr1, uint8_t addr2) { - if (g_pwm_buffer_update_required) { +void IS31FL3737_update_pwm_buffers(uint8_t addr, uint8_t index) { + if (g_pwm_buffer_update_required[index]) { // Firstly we need to unlock the command register and select PG1 - IS31FL3737_write_register(addr1, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); - IS31FL3737_write_register(addr1, ISSI_COMMANDREGISTER, ISSI_PAGE_PWM); + IS31FL3737_write_register(addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); + IS31FL3737_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_PWM); + + IS31FL3737_write_pwm_buffer(addr, g_pwm_buffer[index]); + - IS31FL3737_write_pwm_buffer(addr1, g_pwm_buffer[0]); - // IS31FL3737_write_pwm_buffer(addr2, g_pwm_buffer[1]); } - g_pwm_buffer_update_required = false; + g_pwm_buffer_update_required[index] = false; } -void IS31FL3737_update_led_control_registers(uint8_t addr1, uint8_t addr2) { - if (g_led_control_registers_update_required) { +void IS31FL3737_update_led_control_registers(uint8_t addr, uint8_t index) { + if (g_led_control_registers_update_required[index]) { // Firstly we need to unlock the command register and select PG0 - IS31FL3737_write_register(addr1, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); - IS31FL3737_write_register(addr1, ISSI_COMMANDREGISTER, ISSI_PAGE_LEDCONTROL); + IS31FL3737_write_register(addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); + IS31FL3737_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_LEDCONTROL); for (int i = 0; i < 24; i++) { - IS31FL3737_write_register(addr1, i, g_led_control_registers[0][i]); - // IS31FL3737_write_register(addr2, i, g_led_control_registers[1][i]); + IS31FL3737_write_register(addr, i, g_led_control_registers[index][i]); } - g_led_control_registers_update_required = false; } + g_led_control_registers_update_required[index] = false; } + diff --git a/quantum/rgb_matrix_drivers.c b/quantum/rgb_matrix_drivers.c index 896fa6d0efd5..68b73b18c4d9 100644 --- a/quantum/rgb_matrix_drivers.c +++ b/quantum/rgb_matrix_drivers.c @@ -65,6 +65,9 @@ static void init(void) { # endif # elif defined(IS31FL3737) IS31FL3737_init(DRIVER_ADDR_1); +# ifdef DRIVER_ADDR_2 + IS31FL3737_init(DRIVER_ADDR_2); +# endif # else IS31FL3741_init(DRIVER_ADDR_1); # endif @@ -105,7 +108,10 @@ static void init(void) { IS31FL3733_update_led_control_registers(DRIVER_ADDR_4, 3); # endif # elif defined(IS31FL3737) - IS31FL3737_update_led_control_registers(DRIVER_ADDR_1, DRIVER_ADDR_2); + IS31FL3737_update_led_control_registers(DRIVER_ADDR_1, 0); +# ifdef DRIVER_ADDR_2 + IS31FL3737_update_led_control_registers(DRIVER_ADDR_2, 1); +# endif # else IS31FL3741_update_led_control_registers(DRIVER_ADDR_1, 0); # endif @@ -152,7 +158,12 @@ const rgb_matrix_driver_t rgb_matrix_driver = { .set_color_all = IS31FL3733_set_color_all, }; # elif defined(IS31FL3737) -static void flush(void) { IS31FL3737_update_pwm_buffers(DRIVER_ADDR_1, DRIVER_ADDR_2); } +static void flush(void) { + IS31FL3737_update_pwm_buffers(DRIVER_ADDR_1, 0); +# ifdef DRIVER_ADDR_2 + IS31FL3737_update_pwm_buffers(DRIVER_ADDR_2, 1); +# endif +} const rgb_matrix_driver_t rgb_matrix_driver = { .init = init, @@ -210,3 +221,4 @@ const rgb_matrix_driver_t rgb_matrix_driver = { .set_color_all = setled_all, }; #endif +// touching file ccullin From 15ad7394d0ebaad444dc3f9bfd07019e72581b05 Mon Sep 17 00:00:00 2001 From: ccullin Date: Mon, 5 Jul 2021 21:24:52 +1000 Subject: [PATCH 2/5] removed changes to write_pwm_buffer --- drivers/issi/is31fl3737.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/issi/is31fl3737.c b/drivers/issi/is31fl3737.c index cdc3341a2950..c8de4144c98d 100644 --- a/drivers/issi/is31fl3737.c +++ b/drivers/issi/is31fl3737.c @@ -89,7 +89,7 @@ void IS31FL3737_write_register(uint8_t addr, uint8_t reg, uint8_t data) { #endif } -bool IS31FL3737_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer) { +void IS31FL3737_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer) { // assumes PG1 is already selected // transmit PWM registers in 12 transfers of 16 bytes @@ -107,17 +107,12 @@ bool IS31FL3737_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer) { #if ISSI_PERSISTENCE > 0 for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) { - if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT) != 0) { - return false; - } + if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT) == 0) break; } #else - if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT) != 0) { - return false; - } + i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT); #endif } - return true; } void IS31FL3737_init(uint8_t addr) { From 92360b82ce36d30747a5b00b090c2ce9d34eb49c Mon Sep 17 00:00:00 2001 From: ccullin Date: Tue, 6 Jul 2021 00:02:27 +1000 Subject: [PATCH 3/5] backward compatbility added --- quantum/rgb_matrix_drivers.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/quantum/rgb_matrix_drivers.c b/quantum/rgb_matrix_drivers.c index 68b73b18c4d9..f0be20e73086 100644 --- a/quantum/rgb_matrix_drivers.c +++ b/quantum/rgb_matrix_drivers.c @@ -65,7 +65,7 @@ static void init(void) { # endif # elif defined(IS31FL3737) IS31FL3737_init(DRIVER_ADDR_1); -# ifdef DRIVER_ADDR_2 +# ifdef DRIVER_ADDR_2 && (DRIVER_ADDR_2 != DRIVER_ADDR_1) IS31FL3737_init(DRIVER_ADDR_2); # endif # else @@ -109,7 +109,7 @@ static void init(void) { # endif # elif defined(IS31FL3737) IS31FL3737_update_led_control_registers(DRIVER_ADDR_1, 0); -# ifdef DRIVER_ADDR_2 +# ifdef DRIVER_ADDR_2 && (DRIVER_ADDR_2 != DRIVER_ADDR_1) IS31FL3737_update_led_control_registers(DRIVER_ADDR_2, 1); # endif # else @@ -160,7 +160,7 @@ const rgb_matrix_driver_t rgb_matrix_driver = { # elif defined(IS31FL3737) static void flush(void) { IS31FL3737_update_pwm_buffers(DRIVER_ADDR_1, 0); -# ifdef DRIVER_ADDR_2 +# ifdef DRIVER_ADDR_2 && (DRIVER_ADDR_2 != DRIVER_ADDR_1) IS31FL3737_update_pwm_buffers(DRIVER_ADDR_2, 1); # endif } From 9e3d1386596a9764c3f77aae5b2f800fed561c3c Mon Sep 17 00:00:00 2001 From: ccullin Date: Tue, 6 Jul 2021 00:20:55 +1000 Subject: [PATCH 4/5] fixed issue with backward compatibility --- quantum/rgb_matrix_drivers.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/quantum/rgb_matrix_drivers.c b/quantum/rgb_matrix_drivers.c index f0be20e73086..ad46c9c52e2b 100644 --- a/quantum/rgb_matrix_drivers.c +++ b/quantum/rgb_matrix_drivers.c @@ -65,7 +65,7 @@ static void init(void) { # endif # elif defined(IS31FL3737) IS31FL3737_init(DRIVER_ADDR_1); -# ifdef DRIVER_ADDR_2 && (DRIVER_ADDR_2 != DRIVER_ADDR_1) +# if defined(DRIVER_ADDR_2) && (DRIVER_ADDR_2 != DRIVER_ADDR_1) // provides backward compatibility IS31FL3737_init(DRIVER_ADDR_2); # endif # else @@ -109,7 +109,7 @@ static void init(void) { # endif # elif defined(IS31FL3737) IS31FL3737_update_led_control_registers(DRIVER_ADDR_1, 0); -# ifdef DRIVER_ADDR_2 && (DRIVER_ADDR_2 != DRIVER_ADDR_1) +# if defined(DRIVER_ADDR_2) && (DRIVER_ADDR_2 != DRIVER_ADDR_1) // provides backward compatibility IS31FL3737_update_led_control_registers(DRIVER_ADDR_2, 1); # endif # else @@ -160,7 +160,7 @@ const rgb_matrix_driver_t rgb_matrix_driver = { # elif defined(IS31FL3737) static void flush(void) { IS31FL3737_update_pwm_buffers(DRIVER_ADDR_1, 0); -# ifdef DRIVER_ADDR_2 && (DRIVER_ADDR_2 != DRIVER_ADDR_1) +# if defined(DRIVER_ADDR_2) && (DRIVER_ADDR_2 != DRIVER_ADDR_1) // provides backward compatibility IS31FL3737_update_pwm_buffers(DRIVER_ADDR_2, 1); # endif } From 4bb9639f490b1cd22817130fac56224cb8fd6f93 Mon Sep 17 00:00:00 2001 From: ccullin Date: Tue, 6 Jul 2021 02:27:25 +1000 Subject: [PATCH 5/5] documentation update --- docs/feature_rgb_matrix.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/feature_rgb_matrix.md b/docs/feature_rgb_matrix.md index 11de4c888162..e49215dcf903 100644 --- a/docs/feature_rgb_matrix.md +++ b/docs/feature_rgb_matrix.md @@ -149,6 +149,18 @@ You can use between 1 and 2 IS31FL3737 IC's. Do not specify `DRIVER_ADDR_2` defi Configure the hardware via your `config.h`: +| Variable | Description | Default | +|----------|-------------|---------| +| `ISSI_TIMEOUT` | (Optional) How long to wait for i2c messages, in milliseconds | 100 | +| `ISSI_PERSISTENCE` | (Optional) Retry failed messages this many times | 0 | +| `DRIVER_COUNT` | (Required) How many RGB driver IC's are present | | +| `DRIVER_LED_TOTAL` | (Required) How many RGB lights are present across all drivers | | +| `DRIVER_ADDR_1` | (Required) Address for the first RGB driver | | +| `DRIVER_ADDR_2` | (Optional) Address for the second RGB driver | | + + +Here is an example using 2 drivers. + ```c // This is a 7-bit address, that gets left-shifted and bit 0 // set to 0 for write, 1 for read (as per I2C protocol)