From a28fbcda2306634c74e196ce98f8bebb701445b0 Mon Sep 17 00:00:00 2001 From: Ryan Date: Tue, 13 Apr 2021 19:51:31 +1000 Subject: Terrazzo: Fix wrong LED Matrix function names (#12561) --- docs/ja/feature_led_matrix.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/ja/feature_led_matrix.md') diff --git a/docs/ja/feature_led_matrix.md b/docs/ja/feature_led_matrix.md index b73487ca63..62e22859fb 100644 --- a/docs/ja/feature_led_matrix.md +++ b/docs/ja/feature_led_matrix.md @@ -76,7 +76,7 @@ I2C IS31FL3731 RGB コントローラを使ったアドレス指定可能な LED カスタムレイヤー効果は `.c` 内で以下を定義することで行うことができます: void led_matrix_indicators_kb(void) { - led_matrix_set_index_value(index, value); + led_matrix_set_value(index, value); } 同様の関数がキーマップ内で `led_matrix_indicators_user` として動作します。 -- cgit v1.2.3 From 206a995ccd53b0843e72da606abebe06f39c9c28 Mon Sep 17 00:00:00 2001 From: Joel Challis Date: Sat, 31 Jul 2021 14:31:09 +0100 Subject: Move some led drivers to common folder (#13749) * Move some led drivers to common folder --- common_features.mk | 14 +- docs/feature_led_matrix.md | 2 +- docs/feature_rgb_matrix.md | 6 +- docs/ja/feature_led_matrix.md | 2 +- drivers/apa102/apa102.c | 151 --------- drivers/apa102/apa102.h | 41 --- drivers/awinic/aw20216.c | 141 -------- drivers/awinic/aw20216.h | 252 -------------- drivers/issi/is31fl3218.c | 96 ------ drivers/issi/is31fl3218.h | 25 -- drivers/issi/is31fl3731-simple.c | 233 ------------- drivers/issi/is31fl3731-simple.h | 207 ------------ drivers/issi/is31fl3731.c | 237 ------------- drivers/issi/is31fl3731.h | 208 ------------ drivers/issi/is31fl3733.c | 237 ------------- drivers/issi/is31fl3733.h | 251 -------------- drivers/issi/is31fl3736.c | 269 --------------- drivers/issi/is31fl3736.h | 168 ---------- drivers/issi/is31fl3737.c | 227 ------------- drivers/issi/is31fl3737.h | 203 ------------ drivers/issi/is31fl3741.c | 255 -------------- drivers/issi/is31fl3741.h | 420 ------------------------ drivers/led/apa102.c | 151 +++++++++ drivers/led/apa102.h | 41 +++ drivers/led/aw20216.c | 141 ++++++++ drivers/led/aw20216.h | 252 ++++++++++++++ drivers/led/issi/is31fl3218.c | 96 ++++++ drivers/led/issi/is31fl3218.h | 25 ++ drivers/led/issi/is31fl3731-simple.c | 233 +++++++++++++ drivers/led/issi/is31fl3731-simple.h | 207 ++++++++++++ drivers/led/issi/is31fl3731.c | 237 +++++++++++++ drivers/led/issi/is31fl3731.h | 208 ++++++++++++ drivers/led/issi/is31fl3733.c | 237 +++++++++++++ drivers/led/issi/is31fl3733.h | 251 ++++++++++++++ drivers/led/issi/is31fl3736.c | 269 +++++++++++++++ drivers/led/issi/is31fl3736.h | 168 ++++++++++ drivers/led/issi/is31fl3737.c | 227 +++++++++++++ drivers/led/issi/is31fl3737.h | 203 ++++++++++++ drivers/led/issi/is31fl3741.c | 255 ++++++++++++++ drivers/led/issi/is31fl3741.h | 420 ++++++++++++++++++++++++ keyboards/fallacy/indicators.c | 2 +- keyboards/fallacy/rules.mk | 2 +- keyboards/hs60/v2/ansi/rules.mk | 2 +- keyboards/hs60/v2/hhkb/rules.mk | 2 +- keyboards/hs60/v2/iso/rules.mk | 2 +- keyboards/keebwerk/mega/ansi/ansi.c | 2 +- keyboards/keebwerk/mega/ansi/rules.mk | 2 +- keyboards/nebula12/rules.mk | 2 +- keyboards/nebula68/rules.mk | 2 +- keyboards/nk65/nk65.c | 2 +- keyboards/nk65/rules.mk | 2 +- keyboards/nk87/nk87.c | 2 +- keyboards/nk87/rules.mk | 2 +- keyboards/tkc/portico/rules.mk | 2 +- keyboards/wilba_tech/rama_works_kara/rules.mk | 2 +- keyboards/wilba_tech/rama_works_koyu/rules.mk | 2 +- keyboards/wilba_tech/rama_works_m10_c/rules.mk | 2 +- keyboards/wilba_tech/rama_works_m50_a/rules.mk | 2 +- keyboards/wilba_tech/rama_works_m60_a/rules.mk | 2 +- keyboards/wilba_tech/rama_works_m65_b/rules.mk | 2 +- keyboards/wilba_tech/rama_works_m65_bx/rules.mk | 2 +- keyboards/wilba_tech/rama_works_m6_b/rules.mk | 2 +- keyboards/wilba_tech/rama_works_u80_a/rules.mk | 2 +- keyboards/wilba_tech/wt60_a/rules.mk | 2 +- keyboards/wilba_tech/wt60_b/rules.mk | 2 +- keyboards/wilba_tech/wt60_bx/rules.mk | 2 +- keyboards/wilba_tech/wt60_c/rules.mk | 2 +- keyboards/wilba_tech/wt65_a/rules.mk | 2 +- keyboards/wilba_tech/wt65_b/rules.mk | 2 +- keyboards/wilba_tech/wt75_a/rules.mk | 2 +- keyboards/wilba_tech/wt75_b/rules.mk | 2 +- keyboards/wilba_tech/wt75_c/rules.mk | 2 +- keyboards/wilba_tech/wt80_a/rules.mk | 2 +- keyboards/wilba_tech/wt_mono_backlight.c | 2 +- keyboards/wilba_tech/wt_rgb_backlight.c | 10 +- keyboards/wilba_tech/zeal60/rules.mk | 2 +- keyboards/wilba_tech/zeal65/rules.mk | 2 +- keyboards/xelus/dawn60/rev1/rules.mk | 2 +- keyboards/xelus/dawn60/rev1_qmk/rev1_qmk.c | 2 +- keyboards/xelus/dawn60/rev1_qmk/rules.mk | 2 +- keyboards/xelus/pachi/rgb/rgb.c | 2 +- keyboards/xelus/pachi/rgb/rules.mk | 2 +- 82 files changed, 3679 insertions(+), 3679 deletions(-) delete mode 100644 drivers/apa102/apa102.c delete mode 100644 drivers/apa102/apa102.h delete mode 100644 drivers/awinic/aw20216.c delete mode 100644 drivers/awinic/aw20216.h delete mode 100644 drivers/issi/is31fl3218.c delete mode 100644 drivers/issi/is31fl3218.h delete mode 100644 drivers/issi/is31fl3731-simple.c delete mode 100644 drivers/issi/is31fl3731-simple.h delete mode 100644 drivers/issi/is31fl3731.c delete mode 100644 drivers/issi/is31fl3731.h delete mode 100644 drivers/issi/is31fl3733.c delete mode 100644 drivers/issi/is31fl3733.h delete mode 100644 drivers/issi/is31fl3736.c delete mode 100644 drivers/issi/is31fl3736.h delete mode 100644 drivers/issi/is31fl3737.c delete mode 100644 drivers/issi/is31fl3737.h delete mode 100644 drivers/issi/is31fl3741.c delete mode 100644 drivers/issi/is31fl3741.h create mode 100644 drivers/led/apa102.c create mode 100644 drivers/led/apa102.h create mode 100644 drivers/led/aw20216.c create mode 100644 drivers/led/aw20216.h create mode 100644 drivers/led/issi/is31fl3218.c create mode 100644 drivers/led/issi/is31fl3218.h create mode 100644 drivers/led/issi/is31fl3731-simple.c create mode 100644 drivers/led/issi/is31fl3731-simple.h create mode 100644 drivers/led/issi/is31fl3731.c create mode 100644 drivers/led/issi/is31fl3731.h create mode 100644 drivers/led/issi/is31fl3733.c create mode 100644 drivers/led/issi/is31fl3733.h create mode 100644 drivers/led/issi/is31fl3736.c create mode 100644 drivers/led/issi/is31fl3736.h create mode 100644 drivers/led/issi/is31fl3737.c create mode 100644 drivers/led/issi/is31fl3737.h create mode 100644 drivers/led/issi/is31fl3741.c create mode 100644 drivers/led/issi/is31fl3741.h (limited to 'docs/ja/feature_led_matrix.md') diff --git a/common_features.mk b/common_features.mk index d8dce8a631..75a9e1f2eb 100644 --- a/common_features.mk +++ b/common_features.mk @@ -242,7 +242,7 @@ endif ifeq ($(strip $(LED_MATRIX_DRIVER)), IS31FL3731) OPT_DEFS += -DIS31FL3731 -DSTM32_I2C -DHAL_USE_I2C=TRUE - COMMON_VPATH += $(DRIVER_PATH)/issi + COMMON_VPATH += $(DRIVER_PATH)/led/issi SRC += is31fl3731-simple.c QUANTUM_LIB_SRC += i2c_master.c endif @@ -272,35 +272,35 @@ endif ifeq ($(strip $(RGB_MATRIX_DRIVER)), AW20216) OPT_DEFS += -DAW20216 -DSTM32_SPI -DHAL_USE_SPI=TRUE - COMMON_VPATH += $(DRIVER_PATH)/awinic + COMMON_VPATH += $(DRIVER_PATH)/led SRC += aw20216.c QUANTUM_LIB_SRC += spi_master.c endif ifeq ($(strip $(RGB_MATRIX_DRIVER)), IS31FL3731) OPT_DEFS += -DIS31FL3731 -DSTM32_I2C -DHAL_USE_I2C=TRUE - COMMON_VPATH += $(DRIVER_PATH)/issi + COMMON_VPATH += $(DRIVER_PATH)/led/issi SRC += is31fl3731.c QUANTUM_LIB_SRC += i2c_master.c endif ifeq ($(strip $(RGB_MATRIX_DRIVER)), IS31FL3733) OPT_DEFS += -DIS31FL3733 -DSTM32_I2C -DHAL_USE_I2C=TRUE - COMMON_VPATH += $(DRIVER_PATH)/issi + COMMON_VPATH += $(DRIVER_PATH)/led/issi SRC += is31fl3733.c QUANTUM_LIB_SRC += i2c_master.c endif ifeq ($(strip $(RGB_MATRIX_DRIVER)), IS31FL3737) OPT_DEFS += -DIS31FL3737 -DSTM32_I2C -DHAL_USE_I2C=TRUE - COMMON_VPATH += $(DRIVER_PATH)/issi + COMMON_VPATH += $(DRIVER_PATH)/led/issi SRC += is31fl3737.c QUANTUM_LIB_SRC += i2c_master.c endif ifeq ($(strip $(RGB_MATRIX_DRIVER)), IS31FL3741) OPT_DEFS += -DIS31FL3741 -DSTM32_I2C -DHAL_USE_I2C=TRUE - COMMON_VPATH += $(DRIVER_PATH)/issi + COMMON_VPATH += $(DRIVER_PATH)/led/issi SRC += is31fl3741.c QUANTUM_LIB_SRC += i2c_master.c endif @@ -417,7 +417,7 @@ ifeq ($(strip $(WS2812_DRIVER_REQUIRED)), yes) endif ifeq ($(strip $(APA102_DRIVER_REQUIRED)), yes) - COMMON_VPATH += $(DRIVER_PATH)/apa102 + COMMON_VPATH += $(DRIVER_PATH)/led SRC += apa102.c endif diff --git a/docs/feature_led_matrix.md b/docs/feature_led_matrix.md index 018da43dd1..afa11e7232 100644 --- a/docs/feature_led_matrix.md +++ b/docs/feature_led_matrix.md @@ -63,7 +63,7 @@ const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { } ``` -Where `Cx_y` is the location of the LED in the matrix defined by [the datasheet](https://www.issi.com/WW/pdf/31FL3731.pdf) and the header file `drivers/issi/is31fl3731-simple.h`. The `driver` is the index of the driver you defined in your `config.h` (`0`, `1`, `2`, or `3` ). +Where `Cx_y` is the location of the LED in the matrix defined by [the datasheet](https://www.issi.com/WW/pdf/31FL3731.pdf) and the header file `drivers/led/issi/is31fl3731-simple.h`. The `driver` is the index of the driver you defined in your `config.h` (`0`, `1`, `2`, or `3` ). --- diff --git a/docs/feature_rgb_matrix.md b/docs/feature_rgb_matrix.md index bd47fb6d39..18e38955ec 100644 --- a/docs/feature_rgb_matrix.md +++ b/docs/feature_rgb_matrix.md @@ -64,7 +64,7 @@ const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { } ``` -Where `Cx_y` is the location of the LED in the matrix defined by [the datasheet](https://www.issi.com/WW/pdf/31FL3731.pdf) and the header file `drivers/issi/is31fl3731.h`. The `driver` is the index of the driver you defined in your `config.h` (`0`, `1`, `2`, or `3`). +Where `Cx_y` is the location of the LED in the matrix defined by [the datasheet](https://www.issi.com/WW/pdf/31FL3731.pdf) and the header file `drivers/led/issi/is31fl3731.h`. The `driver` is the index of the driver you defined in your `config.h` (`0`, `1`, `2`, or `3`). --- ### IS31FL3733 :id=is31fl3733 @@ -134,7 +134,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/31FL3733.pdf) and the header file `drivers/issi/is31fl3733.h`. The `driver` is the index of the driver you defined in your `config.h` (`0`, `1`, `2`, or `3` for now). +Where `X_Y` is the location of the LED in the matrix defined by [the datasheet](https://www.issi.com/WW/pdf/31FL3733.pdf) and the header file `drivers/led/issi/is31fl3733.h`. The `driver` is the index of the driver you defined in your `config.h` (`0`, `1`, `2`, or `3` for now). --- ### IS31FL3737 :id=is31fl3737 @@ -198,7 +198,7 @@ const is31_led PROGMEM 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`, `1` for 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/led/issi/is31fl3737.h`. The `driver` is the index of the driver you defined in your `config.h` (Only `0`, `1` for now). --- diff --git a/docs/ja/feature_led_matrix.md b/docs/ja/feature_led_matrix.md index 62e22859fb..f132d716f6 100644 --- a/docs/ja/feature_led_matrix.md +++ b/docs/ja/feature_led_matrix.md @@ -61,7 +61,7 @@ I2C IS31FL3731 RGB コントローラを使ったアドレス指定可能な LED .... } -ここで、`Cx_y` は[データシート](https://www.issi.com/WW/pdf/31FL3731.pdf)およびヘッダファイル `drivers/issi/is31fl3731-simple.h` で定義されるマトリックス内の LED の位置です。`driver` は `config.h` で定義したドライバのインデックス(`0`、`1`、`2`、`3`のいずれか)です。 +ここで、`Cx_y` は[データシート](https://www.issi.com/WW/pdf/31FL3731.pdf)およびヘッダファイル `drivers/led/issi/is31fl3731-simple.h` で定義されるマトリックス内の LED の位置です。`driver` は `config.h` で定義したドライバのインデックス(`0`、`1`、`2`、`3`のいずれか)です。 ## キーコード diff --git a/drivers/apa102/apa102.c b/drivers/apa102/apa102.c deleted file mode 100644 index 7396dc3c55..0000000000 --- a/drivers/apa102/apa102.c +++ /dev/null @@ -1,151 +0,0 @@ -/* Copyright 2020 Aldehir Rojas - * Copyright 2017 Mikkel (Duckle29) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "apa102.h" -#include "quantum.h" - -#ifndef APA102_NOPS -# if defined(__AVR__) -# define APA102_NOPS 0 // AVR at 16 MHz already spends 62.5 ns per clock, so no extra delay is needed -# elif defined(PROTOCOL_CHIBIOS) - -# include "hal.h" -# if defined(STM32F0XX) || defined(STM32F1XX) || defined(STM32F3XX) || defined(STM32F4XX) || defined(STM32L0XX) -# define APA102_NOPS (100 / (1000000000L / (STM32_SYSCLK / 4))) // This calculates how many loops of 4 nops to run to delay 100 ns -# else -# error("APA102_NOPS configuration required") -# define APA102_NOPS 0 // this just pleases the compile so the above error is easier to spot -# endif -# endif -#endif - -#define io_wait \ - do { \ - for (int i = 0; i < APA102_NOPS; i++) { \ - __asm__ volatile("nop\n\t" \ - "nop\n\t" \ - "nop\n\t" \ - "nop\n\t"); \ - } \ - } while (0) - -#define APA102_SEND_BIT(byte, bit) \ - do { \ - writePin(RGB_DI_PIN, (byte >> bit) & 1); \ - io_wait; \ - writePinHigh(RGB_CI_PIN); \ - io_wait; \ - writePinLow(RGB_CI_PIN); \ - io_wait; \ - } while (0) - -uint8_t apa102_led_brightness = APA102_DEFAULT_BRIGHTNESS; - -void static apa102_start_frame(void); -void static apa102_end_frame(uint16_t num_leds); - -void static apa102_send_frame(uint8_t red, uint8_t green, uint8_t blue, uint8_t brightness); -void static apa102_send_byte(uint8_t byte); - -void apa102_setleds(LED_TYPE *start_led, uint16_t num_leds) { - LED_TYPE *end = start_led + num_leds; - - apa102_start_frame(); - for (LED_TYPE *led = start_led; led < end; led++) { - apa102_send_frame(led->r, led->g, led->b, apa102_led_brightness); - } - apa102_end_frame(num_leds); -} - -// Overwrite the default rgblight_call_driver to use apa102 driver -void rgblight_call_driver(LED_TYPE *start_led, uint8_t num_leds) { apa102_setleds(start_led, num_leds); } - -void static apa102_init(void) { - setPinOutput(RGB_DI_PIN); - setPinOutput(RGB_CI_PIN); - - writePinLow(RGB_DI_PIN); - writePinLow(RGB_CI_PIN); -} - -void apa102_set_brightness(uint8_t brightness) { - if (brightness > APA102_MAX_BRIGHTNESS) { - apa102_led_brightness = APA102_MAX_BRIGHTNESS; - } else if (brightness < 0) { - apa102_led_brightness = 0; - } else { - apa102_led_brightness = brightness; - } -} - -void static apa102_send_frame(uint8_t red, uint8_t green, uint8_t blue, uint8_t brightness) { - apa102_send_byte(0b11100000 | brightness); - apa102_send_byte(blue); - apa102_send_byte(green); - apa102_send_byte(red); -} - -void static apa102_start_frame(void) { - apa102_init(); - for (uint16_t i = 0; i < 4; i++) { - apa102_send_byte(0); - } -} - -void static apa102_end_frame(uint16_t num_leds) { - // This function has been taken from: https://github.com/pololu/apa102-arduino/blob/master/APA102.h - // and adapted. The code is MIT licensed. I think thats compatible? - // - // The data stream seen by the last LED in the chain will be delayed by - // (count - 1) clock edges, because each LED before it inverts the clock - // line and delays the data by one clock edge. Therefore, to make sure - // the last LED actually receives the data we wrote, the number of extra - // edges we send at the end of the frame must be at least (count - 1). - // - // Assuming we only want to send these edges in groups of size K, the - // C/C++ expression for the minimum number of groups to send is: - // - // ((count - 1) + (K - 1)) / K - // - // The C/C++ expression above is just (count - 1) divided by K, - // rounded up to the nearest whole number if there is a remainder. - // - // We set K to 16 and use the formula above as the number of frame-end - // bytes to transfer. Each byte has 16 clock edges. - // - // We are ignoring the specification for the end frame in the APA102 - // datasheet, which says to send 0xFF four times, because it does not work - // when you have 66 LEDs or more, and also it results in unwanted white - // pixels if you try to update fewer LEDs than are on your LED strip. - uint16_t iterations = (num_leds + 14) / 16; - for (uint16_t i = 0; i < iterations; i++) { - apa102_send_byte(0); - } - - apa102_init(); -} - -void static apa102_send_byte(uint8_t byte) { - APA102_SEND_BIT(byte, 7); - APA102_SEND_BIT(byte, 6); - APA102_SEND_BIT(byte, 5); - APA102_SEND_BIT(byte, 4); - APA102_SEND_BIT(byte, 3); - APA102_SEND_BIT(byte, 2); - APA102_SEND_BIT(byte, 1); - APA102_SEND_BIT(byte, 0); -} diff --git a/drivers/apa102/apa102.h b/drivers/apa102/apa102.h deleted file mode 100644 index 58cf020c1e..0000000000 --- a/drivers/apa102/apa102.h +++ /dev/null @@ -1,41 +0,0 @@ -/* Copyright 2020 Aldehir Rojas - * Copyright 2017 Mikkel (Duckle29) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#pragma once - -#include "color.h" - -#ifndef APA102_DEFAULT_BRIGHTNESS -# define APA102_DEFAULT_BRIGHTNESS 31 -#endif - -#define APA102_MAX_BRIGHTNESS 31 - -extern uint8_t apa102_led_brightness; - -/* User Interface - * - * Input: - * start_led: An array of GRB data describing the LED colors - * num_leds: The number of LEDs to write - * - * The functions will perform the following actions: - * - Set the data-out pin as output - * - Send out the LED data - */ -void apa102_setleds(LED_TYPE *start_led, uint16_t num_leds); -void apa102_set_brightness(uint8_t brightness); diff --git a/drivers/awinic/aw20216.c b/drivers/awinic/aw20216.c deleted file mode 100644 index c608c0ab44..0000000000 --- a/drivers/awinic/aw20216.c +++ /dev/null @@ -1,141 +0,0 @@ -/* Copyright 2021 Jasper Chan - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "aw20216.h" -#include "spi_master.h" - -/* The AW20216 appears to be somewhat similar to the IS31FL743, although quite - * a few things are different, such as the command byte format and page ordering. - * The LED addresses start from 0x00 instead of 0x01. - */ -#define AWINIC_ID 0b1010 << 4 - -#define AW_PAGE_FUNCTION 0x00 << 1 // PG0, Function registers -#define AW_PAGE_PWM 0x01 << 1 // PG1, LED PWM control -#define AW_PAGE_SCALING 0x02 << 1 // PG2, LED current scaling control -#define AW_PAGE_PATCHOICE 0x03 << 1 // PG3, Pattern choice? -#define AW_PAGE_PWMSCALING 0x04 << 1 // PG4, LED PWM + Scaling control? - -#define AW_WRITE 0 -#define AW_READ 1 - -#define AW_REG_CONFIGURATION 0x00 // PG0 -#define AW_REG_GLOBALCURRENT 0x01 // PG0 - -// Default value of AW_REG_CONFIGURATION -// D7:D4 = 1011, SWSEL (SW1~SW12 active) -// D3 = 0?, reserved (apparently this should be 1 but it doesn't seem to matter) -// D2:D1 = 00, OSDE (open/short detection enable) -// D0 = 0, CHIPEN (write 1 to enable LEDs when hardware enable pulled high) -#define AW_CONFIG_DEFAULT 0b10110000 -#define AW_CHIPEN 1 - -#define AW_PWM_REGISTER_COUNT 216 - -#ifndef AW_SCALING_MAX -# define AW_SCALING_MAX 150 -#endif - -#ifndef AW_GLOBAL_CURRENT_MAX -# define AW_GLOBAL_CURRENT_MAX 150 -#endif - -#ifndef AW_SPI_DIVISOR -# define AW_SPI_DIVISOR 4 -#endif - -uint8_t g_pwm_buffer[DRIVER_COUNT][AW_PWM_REGISTER_COUNT]; -bool g_pwm_buffer_update_required[DRIVER_COUNT] = {false}; - -bool AW20216_write(pin_t cs_pin, uint8_t page, uint8_t reg, uint8_t* data, uint8_t len) { - static uint8_t s_spi_transfer_buffer[2] = {0}; - - if (!spi_start(cs_pin, false, 0, AW_SPI_DIVISOR)) { - spi_stop(); - return false; - } - - s_spi_transfer_buffer[0] = (AWINIC_ID | page | AW_WRITE); - s_spi_transfer_buffer[1] = reg; - - if (spi_transmit(s_spi_transfer_buffer, 2) != SPI_STATUS_SUCCESS) { - spi_stop(); - return false; - } - - if (spi_transmit(data, len) != SPI_STATUS_SUCCESS) { - spi_stop(); - return false; - } - - spi_stop(); - return true; -} - -static inline bool AW20216_write_register(pin_t cs_pin, uint8_t page, uint8_t reg, uint8_t value) { - // Little wrapper so callers need not care about sending a buffer - return AW20216_write(cs_pin, page, reg, &value, 1); -} - -static void AW20216_init_scaling(pin_t cs_pin) { - // Set constant current to the max, control brightness with PWM - for (uint8_t i = 0; i < AW_PWM_REGISTER_COUNT; i++) { - AW20216_write_register(cs_pin, AW_PAGE_SCALING, i, AW_SCALING_MAX); - } -} - -static inline void AW20216_init_current_limit(pin_t cs_pin) { - // Push config - AW20216_write_register(cs_pin, AW_PAGE_FUNCTION, AW_REG_GLOBALCURRENT, AW_GLOBAL_CURRENT_MAX); -} - -static inline void AW20216_soft_enable(pin_t cs_pin) { - // Push config - AW20216_write_register(cs_pin, AW_PAGE_FUNCTION, AW_REG_CONFIGURATION, AW_CONFIG_DEFAULT | AW_CHIPEN); -} - -void AW20216_init(pin_t cs_pin, pin_t en_pin) { - setPinOutput(en_pin); - writePinHigh(en_pin); - - // Drivers should start with all scaling and PWM registers as off - AW20216_init_current_limit(cs_pin); - AW20216_init_scaling(cs_pin); - - AW20216_soft_enable(cs_pin); -} - -void AW20216_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { - aw_led led = g_aw_leds[index]; - - 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[led.driver] = true; -} - -void AW20216_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { - for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) { - AW20216_set_color(i, red, green, blue); - } -} - -void AW20216_update_pwm_buffers(pin_t cs_pin, uint8_t index) { - if (g_pwm_buffer_update_required[index]) { - AW20216_write(cs_pin, AW_PAGE_PWM, 0, g_pwm_buffer[index], AW_PWM_REGISTER_COUNT); - } - g_pwm_buffer_update_required[index] = false; -} diff --git a/drivers/awinic/aw20216.h b/drivers/awinic/aw20216.h deleted file mode 100644 index c55d9605fc..0000000000 --- a/drivers/awinic/aw20216.h +++ /dev/null @@ -1,252 +0,0 @@ -/* Copyright 2021 Jasper Chan (Gigahawk) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#pragma once - -#include -#include -#include "gpio.h" - -typedef struct aw_led { - uint8_t driver : 2; - uint8_t r; - uint8_t g; - uint8_t b; -} aw_led; - -extern const aw_led g_aw_leds[DRIVER_LED_TOTAL]; - -void AW20216_init(pin_t cs_pin, pin_t en_pin); -void AW20216_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); -void AW20216_set_color_all(uint8_t red, uint8_t green, uint8_t blue); -void AW20216_update_pwm_buffers(pin_t cs_pin, uint8_t index); - -#define CS1_SW1 0x00 -#define CS2_SW1 0x01 -#define CS3_SW1 0x02 -#define CS4_SW1 0x03 -#define CS5_SW1 0x04 -#define CS6_SW1 0x05 -#define CS7_SW1 0x06 -#define CS8_SW1 0x07 -#define CS9_SW1 0x08 -#define CS10_SW1 0x09 -#define CS11_SW1 0x0A -#define CS12_SW1 0x0B -#define CS13_SW1 0x0C -#define CS14_SW1 0x0D -#define CS15_SW1 0x0E -#define CS16_SW1 0x0F -#define CS17_SW1 0x10 -#define CS18_SW1 0x11 -#define CS1_SW2 0x12 -#define CS2_SW2 0x13 -#define CS3_SW2 0x14 -#define CS4_SW2 0x15 -#define CS5_SW2 0x16 -#define CS6_SW2 0x17 -#define CS7_SW2 0x18 -#define CS8_SW2 0x19 -#define CS9_SW2 0x1A -#define CS10_SW2 0x1B -#define CS11_SW2 0x1C -#define CS12_SW2 0x1D -#define CS13_SW2 0x1E -#define CS14_SW2 0x1F -#define CS15_SW2 0x20 -#define CS16_SW2 0x21 -#define CS17_SW2 0x22 -#define CS18_SW2 0x23 -#define CS1_SW3 0x24 -#define CS2_SW3 0x25 -#define CS3_SW3 0x26 -#define CS4_SW3 0x27 -#define CS5_SW3 0x28 -#define CS6_SW3 0x29 -#define CS7_SW3 0x2A -#define CS8_SW3 0x2B -#define CS9_SW3 0x2C -#define CS10_SW3 0x2D -#define CS11_SW3 0x2E -#define CS12_SW3 0x2F -#define CS13_SW3 0x30 -#define CS14_SW3 0x31 -#define CS15_SW3 0x32 -#define CS16_SW3 0x33 -#define CS17_SW3 0x34 -#define CS18_SW3 0x35 -#define CS1_SW4 0x36 -#define CS2_SW4 0x37 -#define CS3_SW4 0x38 -#define CS4_SW4 0x39 -#define CS5_SW4 0x3A -#define CS6_SW4 0x3B -#define CS7_SW4 0x3C -#define CS8_SW4 0x3D -#define CS9_SW4 0x3E -#define CS10_SW4 0x3F -#define CS11_SW4 0x40 -#define CS12_SW4 0x41 -#define CS13_SW4 0x42 -#define CS14_SW4 0x43 -#define CS15_SW4 0x44 -#define CS16_SW4 0x45 -#define CS17_SW4 0x46 -#define CS18_SW4 0x47 -#define CS1_SW5 0x48 -#define CS2_SW5 0x49 -#define CS3_SW5 0x4A -#define CS4_SW5 0x4B -#define CS5_SW5 0x4C -#define CS6_SW5 0x4D -#define CS7_SW5 0x4E -#define CS8_SW5 0x4F -#define CS9_SW5 0x50 -#define CS10_SW5 0x51 -#define CS11_SW5 0x52 -#define CS12_SW5 0x53 -#define CS13_SW5 0x54 -#define CS14_SW5 0x55 -#define CS15_SW5 0x56 -#define CS16_SW5 0x57 -#define CS17_SW5 0x58 -#define CS18_SW5 0x59 -#define CS1_SW6 0x5A -#define CS2_SW6 0x5B -#define CS3_SW6 0x5C -#define CS4_SW6 0x5D -#define CS5_SW6 0x5E -#define CS6_SW6 0x5F -#define CS7_SW6 0x60 -#define CS8_SW6 0x61 -#define CS9_SW6 0x62 -#define CS10_SW6 0x63 -#define CS11_SW6 0x64 -#define CS12_SW6 0x65 -#define CS13_SW6 0x66 -#define CS14_SW6 0x67 -#define CS15_SW6 0x68 -#define CS16_SW6 0x69 -#define CS17_SW6 0x6A -#define CS18_SW6 0x6B -#define CS1_SW7 0x6C -#define CS2_SW7 0x6D -#define CS3_SW7 0x6E -#define CS4_SW7 0x6F -#define CS5_SW7 0x70 -#define CS6_SW7 0x71 -#define CS7_SW7 0x72 -#define CS8_SW7 0x73 -#define CS9_SW7 0x74 -#define CS10_SW7 0x75 -#define CS11_SW7 0x76 -#define CS12_SW7 0x77 -#define CS13_SW7 0x78 -#define CS14_SW7 0x79 -#define CS15_SW7 0x7A -#define CS16_SW7 0x7B -#define CS17_SW7 0x7C -#define CS18_SW7 0x7D -#define CS1_SW8 0x7E -#define CS2_SW8 0x7F -#define CS3_SW8 0x80 -#define CS4_SW8 0x81 -#define CS5_SW8 0x82 -#define CS6_SW8 0x83 -#define CS7_SW8 0x84 -#define CS8_SW8 0x85 -#define CS9_SW8 0x86 -#define CS10_SW8 0x87 -#define CS11_SW8 0x88 -#define CS12_SW8 0x89 -#define CS13_SW8 0x8A -#define CS14_SW8 0x8B -#define CS15_SW8 0x8C -#define CS16_SW8 0x8D -#define CS17_SW8 0x8E -#define CS18_SW8 0x8F -#define CS1_SW9 0x90 -#define CS2_SW9 0x91 -#define CS3_SW9 0x92 -#define CS4_SW9 0x93 -#define CS5_SW9 0x94 -#define CS6_SW9 0x95 -#define CS7_SW9 0x96 -#define CS8_SW9 0x97 -#define CS9_SW9 0x98 -#define CS10_SW9 0x99 -#define CS11_SW9 0x9A -#define CS12_SW9 0x9B -#define CS13_SW9 0x9C -#define CS14_SW9 0x9D -#define CS15_SW9 0x9E -#define CS16_SW9 0x9F -#define CS17_SW9 0xA0 -#define CS18_SW9 0xA1 -#define CS1_SW10 0xA2 -#define CS2_SW10 0xA3 -#define CS3_SW10 0xA4 -#define CS4_SW10 0xA5 -#define CS5_SW10 0xA6 -#define CS6_SW10 0xA7 -#define CS7_SW10 0xA8 -#define CS8_SW10 0xA9 -#define CS9_SW10 0xAA -#define CS10_SW10 0xAB -#define CS11_SW10 0xAC -#define CS12_SW10 0xAD -#define CS13_SW10 0xAE -#define CS14_SW10 0xAF -#define CS15_SW10 0xB0 -#define CS16_SW10 0xB1 -#define CS17_SW10 0xB2 -#define CS18_SW10 0xB3 -#define CS1_SW11 0xB4 -#define CS2_SW11 0xB5 -#define CS3_SW11 0xB6 -#define CS4_SW11 0xB7 -#define CS5_SW11 0xB8 -#define CS6_SW11 0xB9 -#define CS7_SW11 0xBA -#define CS8_SW11 0xBB -#define CS9_SW11 0xBC -#define CS10_SW11 0xBD -#define CS11_SW11 0xBE -#define CS12_SW11 0xBF -#define CS13_SW11 0xC0 -#define CS14_SW11 0xC1 -#define CS15_SW11 0xC2 -#define CS16_SW11 0xC3 -#define CS17_SW11 0xC4 -#define CS18_SW11 0xC5 -#define CS1_SW12 0xC6 -#define CS2_SW12 0xC7 -#define CS3_SW12 0xC8 -#define CS4_SW12 0xC9 -#define CS5_SW12 0xCA -#define CS6_SW12 0xCB -#define CS7_SW12 0xCC -#define CS8_SW12 0xCD -#define CS9_SW12 0xCE -#define CS10_SW12 0xCF -#define CS11_SW12 0xD0 -#define CS12_SW12 0xD1 -#define CS13_SW12 0xD2 -#define CS14_SW12 0xD3 -#define CS15_SW12 0xD4 -#define CS16_SW12 0xD5 -#define CS17_SW12 0xD6 -#define CS18_SW12 0xD7 diff --git a/drivers/issi/is31fl3218.c b/drivers/issi/is31fl3218.c deleted file mode 100644 index d43863ac4b..0000000000 --- a/drivers/issi/is31fl3218.c +++ /dev/null @@ -1,96 +0,0 @@ -/* Copyright 2018 Jason Williams (Wilba) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -#include "is31fl3218.h" -#include "i2c_master.h" - -// This is the full 8-bit address -#define ISSI_ADDRESS 0b10101000 - -// These are the register addresses -#define ISSI_REG_SHUTDOWN 0x00 -#define ISSI_REG_PWM 0x01 -#define ISSI_REG_CONTROL 0x13 -#define ISSI_REG_UPDATE 0x16 -#define ISSI_REG_RESET 0x17 - -// Default timeout if no I2C response -#define ISSI_TIMEOUT 100 - -// Reusable buffer for transfers -uint8_t g_twi_transfer_buffer[20]; - -// IS31FL3218 has 18 PWM outputs and a fixed I2C address, so no chaining. -// If used as RGB LED driver, LEDs are assigned RGB,RGB,RGB,RGB,RGB,RGB -uint8_t g_pwm_buffer[18]; -bool g_pwm_buffer_update_required = false; - -void IS31FL3218_write_register(uint8_t reg, uint8_t data) { - g_twi_transfer_buffer[0] = reg; - g_twi_transfer_buffer[1] = data; - i2c_transmit(ISSI_ADDRESS, g_twi_transfer_buffer, 2, ISSI_TIMEOUT); -} - -void IS31FL3218_write_pwm_buffer(uint8_t *pwm_buffer) { - g_twi_transfer_buffer[0] = ISSI_REG_PWM; - for (int i = 0; i < 18; i++) { - g_twi_transfer_buffer[1 + i] = pwm_buffer[i]; - } - - i2c_transmit(ISSI_ADDRESS, g_twi_transfer_buffer, 19, ISSI_TIMEOUT); -} - -void IS31FL3218_init(void) { - // In case we ever want to reinitialize (?) - IS31FL3218_write_register(ISSI_REG_RESET, 0x00); - - // Turn off software shutdown - IS31FL3218_write_register(ISSI_REG_SHUTDOWN, 0x01); - - // Set all PWM values to zero - for (uint8_t i = 0; i < 18; i++) { - IS31FL3218_write_register(ISSI_REG_PWM + i, 0x00); - } - - // Enable all channels - for (uint8_t i = 0; i < 3; i++) { - IS31FL3218_write_register(ISSI_REG_CONTROL + i, 0b00111111); - } - - // Load PWM registers and LED Control register data - IS31FL3218_write_register(ISSI_REG_UPDATE, 0x01); -} - -void IS31FL3218_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { - g_pwm_buffer[index * 3 + 0] = red; - g_pwm_buffer[index * 3 + 1] = green; - g_pwm_buffer[index * 3 + 2] = blue; - g_pwm_buffer_update_required = true; -} - -void IS31FL3218_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { - for (int i = 0; i < 6; i++) { - IS31FL3218_set_color(i, red, green, blue); - } -} - -void IS31FL3218_update_pwm_buffers(void) { - if (g_pwm_buffer_update_required) { - IS31FL3218_write_pwm_buffer(g_pwm_buffer); - // Load PWM registers and LED Control register data - IS31FL3218_write_register(ISSI_REG_UPDATE, 0x01); - } - g_pwm_buffer_update_required = false; -} diff --git a/drivers/issi/is31fl3218.h b/drivers/issi/is31fl3218.h deleted file mode 100644 index fa760da191..0000000000 --- a/drivers/issi/is31fl3218.h +++ /dev/null @@ -1,25 +0,0 @@ -/* Copyright 2018 Jason Williams (Wilba) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#pragma once - -#include -#include - -void IS31FL3218_init(void); -void IS31FL3218_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); -void IS31FL3218_set_color_all(uint8_t red, uint8_t green, uint8_t blue); -void IS31FL3218_update_pwm_buffers(void); diff --git a/drivers/issi/is31fl3731-simple.c b/drivers/issi/is31fl3731-simple.c deleted file mode 100644 index d295772f5e..0000000000 --- a/drivers/issi/is31fl3731-simple.c +++ /dev/null @@ -1,233 +0,0 @@ -/* Copyright 2017 Jason Williams - * Copyright 2018 Jack Humbert - * Copyright 2019 Clueboard - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "is31fl3731-simple.h" -#include "i2c_master.h" -#include "wait.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) -// The address will vary depending on your wiring: -// 0b1110100 AD <-> GND -// 0b1110111 AD <-> VCC -// 0b1110101 AD <-> SCL -// 0b1110110 AD <-> SDA -#define ISSI_ADDR_DEFAULT 0x74 - -#define ISSI_REG_CONFIG 0x00 -#define ISSI_REG_CONFIG_PICTUREMODE 0x00 -#define ISSI_REG_CONFIG_AUTOPLAYMODE 0x08 -#define ISSI_REG_CONFIG_AUDIOPLAYMODE 0x18 - -#define ISSI_CONF_PICTUREMODE 0x00 -#define ISSI_CONF_AUTOFRAMEMODE 0x04 -#define ISSI_CONF_AUDIOMODE 0x08 - -#define ISSI_REG_PICTUREFRAME 0x01 - -#define ISSI_REG_SHUTDOWN 0x0A -#define ISSI_REG_AUDIOSYNC 0x06 - -#define ISSI_COMMANDREGISTER 0xFD -#define ISSI_BANK_FUNCTIONREG 0x0B // helpfully called 'page nine' - -#ifndef ISSI_TIMEOUT -# define ISSI_TIMEOUT 100 -#endif - -#ifndef ISSI_PERSISTENCE -# define ISSI_PERSISTENCE 0 -#endif - -// Transfer buffer for TWITransmitData() -uint8_t g_twi_transfer_buffer[20]; - -// These buffers match the IS31FL3731 PWM registers 0x24-0xB3. -// Storing them like this is optimal for I2C transfers to the registers. -// We could optimize this and take out the unused registers from these -// buffers and the transfers in IS31FL3731_write_pwm_buffer() but it's -// probably not worth the extra complexity. -uint8_t g_pwm_buffer[LED_DRIVER_COUNT][144]; -bool g_pwm_buffer_update_required[LED_DRIVER_COUNT] = {false}; - -/* There's probably a better way to init this... */ -#if LED_DRIVER_COUNT == 1 -uint8_t g_led_control_registers[LED_DRIVER_COUNT][18] = {{0}}; -#elif LED_DRIVER_COUNT == 2 -uint8_t g_led_control_registers[LED_DRIVER_COUNT][18] = {{0}, {0}}; -#elif LED_DRIVER_COUNT == 3 -uint8_t g_led_control_registers[LED_DRIVER_COUNT][18] = {{0}, {0}, {0}}; -#elif LED_DRIVER_COUNT == 4 -uint8_t g_led_control_registers[LED_DRIVER_COUNT][18] = {{0}, {0}, {0}, {0}}; -#endif -bool g_led_control_registers_update_required[LED_DRIVER_COUNT] = {false}; - -// This is the bit pattern in the LED control registers -// (for matrix A, add one to register for matrix B) -// -// reg - b7 b6 b5 b4 b3 b2 b1 b0 -// 0x00 - R08,R07,R06,R05,R04,R03,R02,R01 -// 0x02 - G08,G07,G06,G05,G04,G03,G02,R00 -// 0x04 - B08,B07,B06,B05,B04,B03,G01,G00 -// 0x06 - - , - , - , - , - ,B02,B01,B00 -// 0x08 - - , - , - , - , - , - , - , - -// 0x0A - B17,B16,B15, - , - , - , - , - -// 0x0C - G17,G16,B14,B13,B12,B11,B10,B09 -// 0x0E - R17,G15,G14,G13,G12,G11,G10,G09 -// 0x10 - R16,R15,R14,R13,R12,R11,R10,R09 - -void IS31FL3731_write_register(uint8_t addr, uint8_t reg, uint8_t data) { - g_twi_transfer_buffer[0] = reg; - g_twi_transfer_buffer[1] = data; - -#if ISSI_PERSISTENCE > 0 - for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) { - if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT) == 0) { - break; - } - } -#else - i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT); -#endif -} - -void IS31FL3731_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer) { - // assumes bank is already selected - - // transmit PWM registers in 9 transfers of 16 bytes - // g_twi_transfer_buffer[] is 20 bytes - - // iterate over the pwm_buffer contents at 16 byte intervals - for (int i = 0; i < 144; i += 16) { - // set the first register, e.g. 0x24, 0x34, 0x44, etc. - g_twi_transfer_buffer[0] = 0x24 + i; - // copy the data from i to i+15 - // device will auto-increment register for data after the first byte - // thus this sets registers 0x24-0x33, 0x34-0x43, etc. in one transfer - for (int j = 0; j < 16; j++) { - g_twi_transfer_buffer[1 + j] = pwm_buffer[i + j]; - } - -#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; - } -#else - i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT); -#endif - } -} - -void IS31FL3731_init(uint8_t addr) { - // In order to avoid the LEDs being driven with garbage data - // in the LED driver's PWM registers, first enable software shutdown, - // then set up the mode and other settings, clear the PWM registers, - // then disable software shutdown. - - // select "function register" bank - IS31FL3731_write_register(addr, ISSI_COMMANDREGISTER, ISSI_BANK_FUNCTIONREG); - - // enable software shutdown - IS31FL3731_write_register(addr, ISSI_REG_SHUTDOWN, 0x00); - - // this delay was copied from other drivers, might not be needed - wait_ms(10); - - // picture mode - IS31FL3731_write_register(addr, ISSI_REG_CONFIG, ISSI_REG_CONFIG_PICTUREMODE); - // display frame 0 - IS31FL3731_write_register(addr, ISSI_REG_PICTUREFRAME, 0x00); - // audio sync off - IS31FL3731_write_register(addr, ISSI_REG_AUDIOSYNC, 0x00); - - // select bank 0 - IS31FL3731_write_register(addr, ISSI_COMMANDREGISTER, 0); - - // turn off all LEDs in the LED control register - for (int i = 0x00; i <= 0x11; i++) { - IS31FL3731_write_register(addr, i, 0x00); - } - - // turn off all LEDs in the blink control register (not really needed) - for (int i = 0x12; i <= 0x23; i++) { - IS31FL3731_write_register(addr, i, 0x00); - } - - // set PWM on all LEDs to 0 - for (int i = 0x24; i <= 0xB3; i++) { - IS31FL3731_write_register(addr, i, 0x00); - } - - // select "function register" bank - IS31FL3731_write_register(addr, ISSI_COMMANDREGISTER, ISSI_BANK_FUNCTIONREG); - - // disable software shutdown - IS31FL3731_write_register(addr, ISSI_REG_SHUTDOWN, 0x01); - - // select bank 0 and leave it selected. - // most usage after initialization is just writing PWM buffers in bank 0 - // as there's not much point in double-buffering - IS31FL3731_write_register(addr, ISSI_COMMANDREGISTER, 0); -} - -void IS31FL3731_set_value(int index, uint8_t value) { - if (index >= 0 && index < DRIVER_LED_TOTAL) { - is31_led led = g_is31_leds[index]; - - // Subtract 0x24 to get the second index of g_pwm_buffer - g_pwm_buffer[led.driver][led.v - 0x24] = value; - g_pwm_buffer_update_required[led.driver] = true; - } -} - -void IS31FL3731_set_value_all(uint8_t value) { - for (int i = 0; i < DRIVER_LED_TOTAL; i++) { - IS31FL3731_set_value(i, value); - } -} - -void IS31FL3731_set_led_control_register(uint8_t index, bool value) { - is31_led led = g_is31_leds[index]; - - uint8_t control_register = (led.v - 0x24) / 8; - uint8_t bit_value = (led.v - 0x24) % 8; - - if (value) { - g_led_control_registers[led.driver][control_register] |= (1 << bit_value); - } else { - g_led_control_registers[led.driver][control_register] &= ~(1 << bit_value); - } - - g_led_control_registers_update_required[led.driver] = true; -} - -void IS31FL3731_update_pwm_buffers(uint8_t addr, uint8_t index) { - if (g_pwm_buffer_update_required[index]) { - IS31FL3731_write_pwm_buffer(addr, g_pwm_buffer[index]); - g_pwm_buffer_update_required[index] = false; - } -} - -void IS31FL3731_update_led_control_registers(uint8_t addr, uint8_t index) { - if (g_led_control_registers_update_required[index]) { - for (int i = 0; i < 18; i++) { - IS31FL3731_write_register(addr, i, g_led_control_registers[index][i]); - } - g_led_control_registers_update_required[index] = false; - } -} diff --git a/drivers/issi/is31fl3731-simple.h b/drivers/issi/is31fl3731-simple.h deleted file mode 100644 index 9665d6ed35..0000000000 --- a/drivers/issi/is31fl3731-simple.h +++ /dev/null @@ -1,207 +0,0 @@ -/* Copyright 2017 Jason Williams - * Copyright 2018 Jack Humbert - * Copyright 2019 Clueboard - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#pragma once - -#include -#include - -typedef struct is31_led { - uint8_t driver : 2; - uint8_t v; -} __attribute__((packed)) is31_led; - -extern const is31_led g_is31_leds[DRIVER_LED_TOTAL]; - -void IS31FL3731_init(uint8_t addr); -void IS31FL3731_write_register(uint8_t addr, uint8_t reg, uint8_t data); -void IS31FL3731_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer); - -void IS31FL3731_set_value(int index, uint8_t value); -void IS31FL3731_set_value_all(uint8_t value); - -void IS31FL3731_set_led_control_register(uint8_t index, bool value); - -// This should not be called from an interrupt -// (eg. from a timer interrupt). -// Call this while idle (in between matrix scans). -// If the buffer is dirty, it will update the driver with the buffer. -void IS31FL3731_update_pwm_buffers(uint8_t addr, uint8_t index); -void IS31FL3731_update_led_control_registers(uint8_t addr, uint8_t index); - -#define C1_1 0x24 -#define C1_2 0x25 -#define C1_3 0x26 -#define C1_4 0x27 -#define C1_5 0x28 -#define C1_6 0x29 -#define C1_7 0x2A -#define C1_8 0x2B - -#define C1_9 0x2C -#define C1_10 0x2D -#define C1_11 0x2E -#define C1_12 0x2F -#define C1_13 0x30 -#define C1_14 0x31 -#define C1_15 0x32 -#define C1_16 0x33 - -#define C2_1 0x34 -#define C2_2 0x35 -#define C2_3 0x36 -#define C2_4 0x37 -#define C2_5 0x38 -#define C2_6 0x39 -#define C2_7 0x3A -#define C2_8 0x3B - -#define C2_9 0x3C -#define C2_10 0x3D -#define C2_11 0x3E -#define C2_12 0x3F -#define C2_13 0x40 -#define C2_14 0x41 -#define C2_15 0x42 -#define C2_16 0x43 - -#define C3_1 0x44 -#define C3_2 0x45 -#define C3_3 0x46 -#define C3_4 0x47 -#define C3_5 0x48 -#define C3_6 0x49 -#define C3_7 0x4A -#define C3_8 0x4B - -#define C3_9 0x4C -#define C3_10 0x4D -#define C3_11 0x4E -#define C3_12 0x4F -#define C3_13 0x50 -#define C3_14 0x51 -#define C3_15 0x52 -#define C3_16 0x53 - -#define C4_1 0x54 -#define C4_2 0x55 -#define C4_3 0x56 -#define C4_4 0x57 -#define C4_5 0x58 -#define C4_6 0x59 -#define C4_7 0x5A -#define C4_8 0x5B - -#define C4_9 0x5C -#define C4_10 0x5D -#define C4_11 0x5E -#define C4_12 0x5F -#define C4_13 0x60 -#define C4_14 0x61 -#define C4_15 0x62 -#define C4_16 0x63 - -#define C5_1 0x64 -#define C5_2 0x65 -#define C5_3 0x66 -#define C5_4 0x67 -#define C5_5 0x68 -#define C5_6 0x69 -#define C5_7 0x6A -#define C5_8 0x6B - -#define C5_9 0x6C -#define C5_10 0x6D -#define C5_11 0x6E -#define C5_12 0x6F -#define C5_13 0x70 -#define C5_14 0x71 -#define C5_15 0x72 -#define C5_16 0x73 - -#define C6_1 0x74 -#define C6_2 0x75 -#define C6_3 0x76 -#define C6_4 0x77 -#define C6_5 0x78 -#define C6_6 0x79 -#define C6_7 0x7A -#define C6_8 0x7B - -#define C6_9 0x7C -#define C6_10 0x7D -#define C6_11 0x7E -#define C6_12 0x7F -#define C6_13 0x80 -#define C6_14 0x81 -#define C6_15 0x82 -#define C6_16 0x83 - -#define C7_1 0x84 -#define C7_2 0x85 -#define C7_3 0x86 -#define C7_4 0x87 -#define C7_5 0x88 -#define C7_6 0x89 -#define C7_7 0x8A -#define C7_8 0x8B - -#define C7_9 0x8C -#define C7_10 0x8D -#define C7_11 0x8E -#define C7_12 0x8F -#define C7_13 0x90 -#define C7_14 0x91 -#define C7_15 0x92 -#define C7_16 0x93 - -#define C8_1 0x94 -#define C8_2 0x95 -#define C8_3 0x96 -#define C8_4 0x97 -#define C8_5 0x98 -#define C8_6 0x99 -#define C8_7 0x9A -#define C8_8 0x9B - -#define C8_9 0x9C -#define C8_10 0x9D -#define C8_11 0x9E -#define C8_12 0x9F -#define C8_13 0xA0 -#define C8_14 0xA1 -#define C8_15 0xA2 -#define C8_16 0xA3 - -#define C9_1 0xA4 -#define C9_2 0xA5 -#define C9_3 0xA6 -#define C9_4 0xA7 -#define C9_5 0xA8 -#define C9_6 0xA9 -#define C9_7 0xAA -#define C9_8 0xAB - -#define C9_9 0xAC -#define C9_10 0xAD -#define C9_11 0xAE -#define C9_12 0xAF -#define C9_13 0xB0 -#define C9_14 0xB1 -#define C9_15 0xB2 -#define C9_16 0xB3 diff --git a/drivers/issi/is31fl3731.c b/drivers/issi/is31fl3731.c deleted file mode 100644 index 110bdc1be4..0000000000 --- a/drivers/issi/is31fl3731.c +++ /dev/null @@ -1,237 +0,0 @@ -/* Copyright 2017 Jason Williams - * Copyright 2018 Jack Humbert - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "is31fl3731.h" -#include "i2c_master.h" -#include "wait.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) -// The address will vary depending on your wiring: -// 0b1110100 AD <-> GND -// 0b1110111 AD <-> VCC -// 0b1110101 AD <-> SCL -// 0b1110110 AD <-> SDA -#define ISSI_ADDR_DEFAULT 0x74 - -#define ISSI_REG_CONFIG 0x00 -#define ISSI_REG_CONFIG_PICTUREMODE 0x00 -#define ISSI_REG_CONFIG_AUTOPLAYMODE 0x08 -#define ISSI_REG_CONFIG_AUDIOPLAYMODE 0x18 - -#define ISSI_CONF_PICTUREMODE 0x00 -#define ISSI_CONF_AUTOFRAMEMODE 0x04 -#define ISSI_CONF_AUDIOMODE 0x08 - -#define ISSI_REG_PICTUREFRAME 0x01 - -#define ISSI_REG_SHUTDOWN 0x0A -#define ISSI_REG_AUDIOSYNC 0x06 - -#define ISSI_COMMANDREGISTER 0xFD -#define ISSI_BANK_FUNCTIONREG 0x0B // helpfully called 'page nine' - -#ifndef ISSI_TIMEOUT -# define ISSI_TIMEOUT 100 -#endif - -#ifndef ISSI_PERSISTENCE -# define ISSI_PERSISTENCE 0 -#endif - -// Transfer buffer for TWITransmitData() -uint8_t g_twi_transfer_buffer[20]; - -// These buffers match the IS31FL3731 PWM registers 0x24-0xB3. -// Storing them like this is optimal for I2C transfers to the registers. -// We could optimize this and take out the unused registers from these -// buffers and the transfers in IS31FL3731_write_pwm_buffer() but it's -// probably not worth the extra complexity. -uint8_t g_pwm_buffer[DRIVER_COUNT][144]; -bool g_pwm_buffer_update_required[DRIVER_COUNT] = {false}; - -uint8_t g_led_control_registers[DRIVER_COUNT][18] = {{0}}; -bool g_led_control_registers_update_required[DRIVER_COUNT] = {false}; - -// This is the bit pattern in the LED control registers -// (for matrix A, add one to register for matrix B) -// -// reg - b7 b6 b5 b4 b3 b2 b1 b0 -// 0x00 - R08,R07,R06,R05,R04,R03,R02,R01 -// 0x02 - G08,G07,G06,G05,G04,G03,G02,R00 -// 0x04 - B08,B07,B06,B05,B04,B03,G01,G00 -// 0x06 - - , - , - , - , - ,B02,B01,B00 -// 0x08 - - , - , - , - , - , - , - , - -// 0x0A - B17,B16,B15, - , - , - , - , - -// 0x0C - G17,G16,B14,B13,B12,B11,B10,B09 -// 0x0E - R17,G15,G14,G13,G12,G11,G10,G09 -// 0x10 - R16,R15,R14,R13,R12,R11,R10,R09 - -void IS31FL3731_write_register(uint8_t addr, uint8_t reg, uint8_t data) { - g_twi_transfer_buffer[0] = reg; - g_twi_transfer_buffer[1] = data; - -#if ISSI_PERSISTENCE > 0 - for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) { - if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT) == 0) break; - } -#else - i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT); -#endif -} - -void IS31FL3731_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer) { - // assumes bank is already selected - - // transmit PWM registers in 9 transfers of 16 bytes - // g_twi_transfer_buffer[] is 20 bytes - - // iterate over the pwm_buffer contents at 16 byte intervals - for (int i = 0; i < 144; i += 16) { - // set the first register, e.g. 0x24, 0x34, 0x44, etc. - g_twi_transfer_buffer[0] = 0x24 + i; - // copy the data from i to i+15 - // device will auto-increment register for data after the first byte - // thus this sets registers 0x24-0x33, 0x34-0x43, etc. in one transfer - for (int j = 0; j < 16; j++) { - g_twi_transfer_buffer[1 + j] = pwm_buffer[i + j]; - } - -#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; - } -#else - i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT); -#endif - } -} - -void IS31FL3731_init(uint8_t addr) { - // In order to avoid the LEDs being driven with garbage data - // in the LED driver's PWM registers, first enable software shutdown, - // then set up the mode and other settings, clear the PWM registers, - // then disable software shutdown. - - // select "function register" bank - IS31FL3731_write_register(addr, ISSI_COMMANDREGISTER, ISSI_BANK_FUNCTIONREG); - - // enable software shutdown - IS31FL3731_write_register(addr, ISSI_REG_SHUTDOWN, 0x00); - - // this delay was copied from other drivers, might not be needed - wait_ms(10); - - // picture mode - IS31FL3731_write_register(addr, ISSI_REG_CONFIG, ISSI_REG_CONFIG_PICTUREMODE); - // display frame 0 - IS31FL3731_write_register(addr, ISSI_REG_PICTUREFRAME, 0x00); - // audio sync off - IS31FL3731_write_register(addr, ISSI_REG_AUDIOSYNC, 0x00); - - // select bank 0 - IS31FL3731_write_register(addr, ISSI_COMMANDREGISTER, 0); - - // turn off all LEDs in the LED control register - for (int i = 0x00; i <= 0x11; i++) { - IS31FL3731_write_register(addr, i, 0x00); - } - - // turn off all LEDs in the blink control register (not really needed) - for (int i = 0x12; i <= 0x23; i++) { - IS31FL3731_write_register(addr, i, 0x00); - } - - // set PWM on all LEDs to 0 - for (int i = 0x24; i <= 0xB3; i++) { - IS31FL3731_write_register(addr, i, 0x00); - } - - // select "function register" bank - IS31FL3731_write_register(addr, ISSI_COMMANDREGISTER, ISSI_BANK_FUNCTIONREG); - - // disable software shutdown - IS31FL3731_write_register(addr, ISSI_REG_SHUTDOWN, 0x01); - - // select bank 0 and leave it selected. - // most usage after initialization is just writing PWM buffers in bank 0 - // as there's not much point in double-buffering - IS31FL3731_write_register(addr, ISSI_COMMANDREGISTER, 0); -} - -void IS31FL3731_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { - if (index >= 0 && index < DRIVER_LED_TOTAL) { - is31_led led = g_is31_leds[index]; - - // Subtract 0x24 to get the second index of g_pwm_buffer - g_pwm_buffer[led.driver][led.r - 0x24] = red; - g_pwm_buffer[led.driver][led.g - 0x24] = green; - g_pwm_buffer[led.driver][led.b - 0x24] = blue; - g_pwm_buffer_update_required[led.driver] = true; - } -} - -void IS31FL3731_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { - for (int i = 0; i < DRIVER_LED_TOTAL; i++) { - IS31FL3731_set_color(i, red, green, blue); - } -} - -void IS31FL3731_set_led_control_register(uint8_t index, bool red, bool green, bool blue) { - is31_led led = g_is31_leds[index]; - - uint8_t control_register_r = (led.r - 0x24) / 8; - uint8_t control_register_g = (led.g - 0x24) / 8; - uint8_t control_register_b = (led.b - 0x24) / 8; - uint8_t bit_r = (led.r - 0x24) % 8; - uint8_t bit_g = (led.g - 0x24) % 8; - uint8_t bit_b = (led.b - 0x24) % 8; - - if (red) { - g_led_control_registers[led.driver][control_register_r] |= (1 << bit_r); - } else { - g_led_control_registers[led.driver][control_register_r] &= ~(1 << bit_r); - } - if (green) { - g_led_control_registers[led.driver][control_register_g] |= (1 << bit_g); - } else { - g_led_control_registers[led.driver][control_register_g] &= ~(1 << bit_g); - } - if (blue) { - g_led_control_registers[led.driver][control_register_b] |= (1 << bit_b); - } else { - g_led_control_registers[led.driver][control_register_b] &= ~(1 << bit_b); - } - - g_led_control_registers_update_required[led.driver] = true; -} - -void IS31FL3731_update_pwm_buffers(uint8_t addr, uint8_t index) { - if (g_pwm_buffer_update_required[index]) { - IS31FL3731_write_pwm_buffer(addr, g_pwm_buffer[index]); - } - g_pwm_buffer_update_required[index] = false; -} - -void IS31FL3731_update_led_control_registers(uint8_t addr, uint8_t index) { - if (g_led_control_registers_update_required[index]) { - for (int i = 0; i < 18; i++) { - IS31FL3731_write_register(addr, i, g_led_control_registers[index][i]); - } - } - g_led_control_registers_update_required[index] = false; -} diff --git a/drivers/issi/is31fl3731.h b/drivers/issi/is31fl3731.h deleted file mode 100644 index 19e8e6251f..0000000000 --- a/drivers/issi/is31fl3731.h +++ /dev/null @@ -1,208 +0,0 @@ -/* Copyright 2017 Jason Williams - * Copyright 2018 Jack Humbert - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#pragma once - -#include -#include - -typedef struct is31_led { - uint8_t driver : 2; - uint8_t r; - uint8_t g; - uint8_t b; -} __attribute__((packed)) is31_led; - -extern const is31_led g_is31_leds[DRIVER_LED_TOTAL]; - -void IS31FL3731_init(uint8_t addr); -void IS31FL3731_write_register(uint8_t addr, uint8_t reg, uint8_t data); -void IS31FL3731_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer); - -void IS31FL3731_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); -void IS31FL3731_set_color_all(uint8_t red, uint8_t green, uint8_t blue); - -void IS31FL3731_set_led_control_register(uint8_t index, bool red, bool green, bool blue); - -// This should not be called from an interrupt -// (eg. from a timer interrupt). -// Call this while idle (in between matrix scans). -// If the buffer is dirty, it will update the driver with the buffer. -void IS31FL3731_update_pwm_buffers(uint8_t addr, uint8_t index); -void IS31FL3731_update_led_control_registers(uint8_t addr, uint8_t index); - -#define C1_1 0x24 -#define C1_2 0x25 -#define C1_3 0x26 -#define C1_4 0x27 -#define C1_5 0x28 -#define C1_6 0x29 -#define C1_7 0x2A -#define C1_8 0x2B - -#define C1_9 0x2C -#define C1_10 0x2D -#define C1_11 0x2E -#define C1_12 0x2F -#define C1_13 0x30 -#define C1_14 0x31 -#define C1_15 0x32 -#define C1_16 0x33 - -#define C2_1 0x34 -#define C2_2 0x35 -#define C2_3 0x36 -#define C2_4 0x37 -#define C2_5 0x38 -#define C2_6 0x39 -#define C2_7 0x3A -#define C2_8 0x3B - -#define C2_9 0x3C -#define C2_10 0x3D -#define C2_11 0x3E -#define C2_12 0x3F -#define C2_13 0x40 -#define C2_14 0x41 -#define C2_15 0x42 -#define C2_16 0x43 - -#define C3_1 0x44 -#define C3_2 0x45 -#define C3_3 0x46 -#define C3_4 0x47 -#define C3_5 0x48 -#define C3_6 0x49 -#define C3_7 0x4A -#define C3_8 0x4B - -#define C3_9 0x4C -#define C3_10 0x4D -#define C3_11 0x4E -#define C3_12 0x4F -#define C3_13 0x50 -#define C3_14 0x51 -#define C3_15 0x52 -#define C3_16 0x53 - -#define C4_1 0x54 -#define C4_2 0x55 -#define C4_3 0x56 -#define C4_4 0x57 -#define C4_5 0x58 -#define C4_6 0x59 -#define C4_7 0x5A -#define C4_8 0x5B - -#define C4_9 0x5C -#define C4_10 0x5D -#define C4_11 0x5E -#define C4_12 0x5F -#define C4_13 0x60 -#define C4_14 0x61 -#define C4_15 0x62 -#define C4_16 0x63 - -#define C5_1 0x64 -#define C5_2 0x65 -#define C5_3 0x66 -#define C5_4 0x67 -#define C5_5 0x68 -#define C5_6 0x69 -#define C5_7 0x6A -#define C5_8 0x6B - -#define C5_9 0x6C -#define C5_10 0x6D -#define C5_11 0x6E -#define C5_12 0x6F -#define C5_13 0x70 -#define C5_14 0x71 -#define C5_15 0x72 -#define C5_16 0x73 - -#define C6_1 0x74 -#define C6_2 0x75 -#define C6_3 0x76 -#define C6_4 0x77 -#define C6_5 0x78 -#define C6_6 0x79 -#define C6_7 0x7A -#define C6_8 0x7B - -#define C6_9 0x7C -#define C6_10 0x7D -#define C6_11 0x7E -#define C6_12 0x7F -#define C6_13 0x80 -#define C6_14 0x81 -#define C6_15 0x82 -#define C6_16 0x83 - -#define C7_1 0x84 -#define C7_2 0x85 -#define C7_3 0x86 -#define C7_4 0x87 -#define C7_5 0x88 -#define C7_6 0x89 -#define C7_7 0x8A -#define C7_8 0x8B - -#define C7_9 0x8C -#define C7_10 0x8D -#define C7_11 0x8E -#define C7_12 0x8F -#define C7_13 0x90 -#define C7_14 0x91 -#define C7_15 0x92 -#define C7_16 0x93 - -#define C8_1 0x94 -#define C8_2 0x95 -#define C8_3 0x96 -#define C8_4 0x97 -#define C8_5 0x98 -#define C8_6 0x99 -#define C8_7 0x9A -#define C8_8 0x9B - -#define C8_9 0x9C -#define C8_10 0x9D -#define C8_11 0x9E -#define C8_12 0x9F -#define C8_13 0xA0 -#define C8_14 0xA1 -#define C8_15 0xA2 -#define C8_16 0xA3 - -#define C9_1 0xA4 -#define C9_2 0xA5 -#define C9_3 0xA6 -#define C9_4 0xA7 -#define C9_5 0xA8 -#define C9_6 0xA9 -#define C9_7 0xAA -#define C9_8 0xAB - -#define C9_9 0xAC -#define C9_10 0xAD -#define C9_11 0xAE -#define C9_12 0xAF -#define C9_13 0xB0 -#define C9_14 0xB1 -#define C9_15 0xB2 -#define C9_16 0xB3 diff --git a/drivers/issi/is31fl3733.c b/drivers/issi/is31fl3733.c deleted file mode 100644 index d99e5339c9..0000000000 --- a/drivers/issi/is31fl3733.c +++ /dev/null @@ -1,237 +0,0 @@ -/* Copyright 2017 Jason Williams - * Copyright 2018 Jack Humbert - * Copyright 2018 Yiancar - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "is31fl3733.h" -#include "i2c_master.h" -#include "wait.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) -// The address will vary depending on your wiring: -// 00 <-> GND -// 01 <-> SCL -// 10 <-> SDA -// 11 <-> VCC -// ADDR1 represents A1:A0 of the 7-bit address. -// ADDR2 represents A3:A2 of the 7-bit address. -// The result is: 0b101(ADDR2)(ADDR1) -#define ISSI_ADDR_DEFAULT 0x50 - -#define ISSI_COMMANDREGISTER 0xFD -#define ISSI_COMMANDREGISTER_WRITELOCK 0xFE -#define ISSI_INTERRUPTMASKREGISTER 0xF0 -#define ISSI_INTERRUPTSTATUSREGISTER 0xF1 - -#define ISSI_PAGE_LEDCONTROL 0x00 // PG0 -#define ISSI_PAGE_PWM 0x01 // PG1 -#define ISSI_PAGE_AUTOBREATH 0x02 // PG2 -#define ISSI_PAGE_FUNCTION 0x03 // PG3 - -#define ISSI_REG_CONFIGURATION 0x00 // PG3 -#define ISSI_REG_GLOBALCURRENT 0x01 // PG3 -#define ISSI_REG_RESET 0x11 // PG3 -#define ISSI_REG_SWPULLUP 0x0F // PG3 -#define ISSI_REG_CSPULLUP 0x10 // PG3 - -#ifndef ISSI_TIMEOUT -# define ISSI_TIMEOUT 100 -#endif - -#ifndef ISSI_PERSISTENCE -# define ISSI_PERSISTENCE 0 -#endif - -// Transfer buffer for TWITransmitData() -uint8_t g_twi_transfer_buffer[20]; - -// These buffers match the IS31FL3733 PWM registers. -// The control buffers match the PG0 LED On/Off registers. -// Storing them like this is optimal for I2C transfers to the registers. -// We could optimize this and take out the unused registers from these -// buffers and the transfers in IS31FL3733_write_pwm_buffer() but it's -// probably not worth the extra complexity. -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}; - -bool IS31FL3733_write_register(uint8_t addr, uint8_t reg, uint8_t data) { - // If the transaction fails function returns false. - g_twi_transfer_buffer[0] = reg; - g_twi_transfer_buffer[1] = data; - -#if ISSI_PERSISTENCE > 0 - for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) { - if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT) != 0) { - return false; - } - } -#else - if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT) != 0) { - return false; - } -#endif - return true; -} - -bool IS31FL3733_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer) { - // Assumes PG1 is already selected. - // If any of the transactions fails function returns false. - // Transmit PWM registers in 12 transfers of 16 bytes. - // g_twi_transfer_buffer[] is 20 bytes - - // Iterate over the pwm_buffer contents at 16 byte intervals. - for (int i = 0; i < 192; i += 16) { - g_twi_transfer_buffer[0] = i; - // Copy the data from i to i+15. - // Device will auto-increment register for data after the first byte - // Thus this sets registers 0x00-0x0F, 0x10-0x1F, etc. in one transfer. - for (int j = 0; j < 16; j++) { - g_twi_transfer_buffer[1 + j] = pwm_buffer[i + j]; - } - -#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; - } - } -#else - if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT) != 0) { - return false; - } -#endif - } - return true; -} - -void IS31FL3733_init(uint8_t addr, uint8_t sync) { - // In order to avoid the LEDs being driven with garbage data - // in the LED driver's PWM registers, shutdown is enabled last. - // Set up the mode and other settings, clear the PWM registers, - // then disable software shutdown. - // Sync is passed so set it according to the datasheet. - - // Unlock the command register. - IS31FL3733_write_register(addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); - - // Select PG0 - IS31FL3733_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_LEDCONTROL); - // Turn off all LEDs. - for (int i = 0x00; i <= 0x17; i++) { - IS31FL3733_write_register(addr, i, 0x00); - } - - // Unlock the command register. - IS31FL3733_write_register(addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); - - // Select PG1 - IS31FL3733_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_PWM); - // Set PWM on all LEDs to 0 - // No need to setup Breath registers to PWM as that is the default. - for (int i = 0x00; i <= 0xBF; i++) { - IS31FL3733_write_register(addr, i, 0x00); - } - - // Unlock the command register. - IS31FL3733_write_register(addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); - - // Select PG3 - IS31FL3733_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_FUNCTION); - // Set global current to maximum. - IS31FL3733_write_register(addr, ISSI_REG_GLOBALCURRENT, 0xFF); - // Disable software shutdown. - IS31FL3733_write_register(addr, ISSI_REG_CONFIGURATION, (sync << 6) | 0x01); - - // Wait 10ms to ensure the device has woken up. - wait_ms(10); -} - -void IS31FL3733_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { - if (index >= 0 && index < DRIVER_LED_TOTAL) { - is31_led led = g_is31_leds[index]; - - 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[led.driver] = true; - } -} - -void IS31FL3733_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { - for (int i = 0; i < DRIVER_LED_TOTAL; i++) { - IS31FL3733_set_color(i, red, green, blue); - } -} - -void IS31FL3733_set_led_control_register(uint8_t index, bool red, bool green, bool blue) { - is31_led led = g_is31_leds[index]; - - uint8_t control_register_r = led.r / 8; - uint8_t control_register_g = led.g / 8; - uint8_t control_register_b = led.b / 8; - uint8_t bit_r = led.r % 8; - uint8_t bit_g = led.g % 8; - uint8_t bit_b = led.b % 8; - - if (red) { - g_led_control_registers[led.driver][control_register_r] |= (1 << bit_r); - } else { - g_led_control_registers[led.driver][control_register_r] &= ~(1 << bit_r); - } - if (green) { - g_led_control_registers[led.driver][control_register_g] |= (1 << bit_g); - } else { - g_led_control_registers[led.driver][control_register_g] &= ~(1 << bit_g); - } - if (blue) { - g_led_control_registers[led.driver][control_register_b] |= (1 << bit_b); - } else { - g_led_control_registers[led.driver][control_register_b] &= ~(1 << bit_b); - } - - g_led_control_registers_update_required[led.driver] = true; -} - -void IS31FL3733_update_pwm_buffers(uint8_t addr, uint8_t index) { - if (g_pwm_buffer_update_required[index]) { - // Firstly we need to unlock the command register and select PG1. - IS31FL3733_write_register(addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); - IS31FL3733_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_PWM); - - // If any of the transactions fail we risk writing dirty PG0, - // refresh page 0 just in case. - if (!IS31FL3733_write_pwm_buffer(addr, g_pwm_buffer[index])) { - g_led_control_registers_update_required[index] = true; - } - } - g_pwm_buffer_update_required[index] = false; -} - -void IS31FL3733_update_led_control_registers(uint8_t addr, uint8_t index) { - if (g_led_control_registers_update_required[index]) { - // Firstly we need to unlock the command register and select PG0 - IS31FL3733_write_register(addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); - IS31FL3733_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_LEDCONTROL); - for (int i = 0; i < 24; i++) { - IS31FL3733_write_register(addr, i, g_led_control_registers[index][i]); - } - } - g_led_control_registers_update_required[index] = false; -} diff --git a/drivers/issi/is31fl3733.h b/drivers/issi/is31fl3733.h deleted file mode 100644 index 603d505a13..0000000000 --- a/drivers/issi/is31fl3733.h +++ /dev/null @@ -1,251 +0,0 @@ -/* Copyright 2017 Jason Williams - * Copyright 2018 Jack Humbert - * Copyright 2018 Yiancar - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#pragma once - -#include -#include - -typedef struct is31_led { - uint8_t driver : 2; - uint8_t r; - uint8_t g; - uint8_t b; -} __attribute__((packed)) is31_led; - -extern const is31_led g_is31_leds[DRIVER_LED_TOTAL]; - -void IS31FL3733_init(uint8_t addr, uint8_t sync); -bool IS31FL3733_write_register(uint8_t addr, uint8_t reg, uint8_t data); -bool IS31FL3733_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer); - -void IS31FL3733_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); -void IS31FL3733_set_color_all(uint8_t red, uint8_t green, uint8_t blue); - -void IS31FL3733_set_led_control_register(uint8_t index, bool red, bool green, bool blue); - -// This should not be called from an interrupt -// (eg. from a timer interrupt). -// Call this while idle (in between matrix scans). -// If the buffer is dirty, it will update the driver with the buffer. -void IS31FL3733_update_pwm_buffers(uint8_t addr, uint8_t index); -void IS31FL3733_update_led_control_registers(uint8_t addr, uint8_t index); - -#define A_1 0x00 -#define A_2 0x01 -#define A_3 0x02 -#define A_4 0x03 -#define A_5 0x04 -#define A_6 0x05 -#define A_7 0x06 -#define A_8 0x07 -#define A_9 0x08 -#define A_10 0x09 -#define A_11 0x0A -#define A_12 0x0B -#define A_13 0x0C -#define A_14 0x0D -#define A_15 0x0E -#define A_16 0x0F - -#define B_1 0x10 -#define B_2 0x11 -#define B_3 0x12 -#define B_4 0x13 -#define B_5 0x14 -#define B_6 0x15 -#define B_7 0x16 -#define B_8 0x17 -#define B_9 0x18 -#define B_10 0x19 -#define B_11 0x1A -#define B_12 0x1B -#define B_13 0x1C -#define B_14 0x1D -#define B_15 0x1E -#define B_16 0x1F - -#define C_1 0x20 -#define C_2 0x21 -#define C_3 0x22 -#define C_4 0x23 -#define C_5 0x24 -#define C_6 0x25 -#define C_7 0x26 -#define C_8 0x27 -#define C_9 0x28 -#define C_10 0x29 -#define C_11 0x2A -#define C_12 0x2B -#define C_13 0x2C -#define C_14 0x2D -#define C_15 0x2E -#define C_16 0x2F - -#define D_1 0x30 -#define D_2 0x31 -#define D_3 0x32 -#define D_4 0x33 -#define D_5 0x34 -#define D_6 0x35 -#define D_7 0x36 -#define D_8 0x37 -#define D_9 0x38 -#define D_10 0x39 -#define D_11 0x3A -#define D_12 0x3B -#define D_13 0x3C -#define D_14 0x3D -#define D_15 0x3E -#define D_16 0x3F - -#define E_1 0x40 -#define E_2 0x41 -#define E_3 0x42 -#define E_4 0x43 -#define E_5 0x44 -#define E_6 0x45 -#define E_7 0x46 -#define E_8 0x47 -#define E_9 0x48 -#define E_10 0x49 -#define E_11 0x4A -#define E_12 0x4B -#define E_13 0x4C -#define E_14 0x4D -#define E_15 0x4E -#define E_16 0x4F - -#define F_1 0x50 -#define F_2 0x51 -#define F_3 0x52 -#define F_4 0x53 -#define F_5 0x54 -#define F_6 0x55 -#define F_7 0x56 -#define F_8 0x57 -#define F_9 0x58 -#define F_10 0x59 -#define F_11 0x5A -#define F_12 0x5B -#define F_13 0x5C -#define F_14 0x5D -#define F_15 0x5E -#define F_16 0x5F - -#define G_1 0x60 -#define G_2 0x61 -#define G_3 0x62 -#define G_4 0x63 -#define G_5 0x64 -#define G_6 0x65 -#define G_7 0x66 -#define G_8 0x67 -#define G_9 0x68 -#define G_10 0x69 -#define G_11 0x6A -#define G_12 0x6B -#define G_13 0x6C -#define G_14 0x6D -#define G_15 0x6E -#define G_16 0x6F - -#define H_1 0x70 -#define H_2 0x71 -#define H_3 0x72 -#define H_4 0x73 -#define H_5 0x74 -#define H_6 0x75 -#define H_7 0x76 -#define H_8 0x77 -#define H_9 0x78 -#define H_10 0x79 -#define H_11 0x7A -#define H_12 0x7B -#define H_13 0x7C -#define H_14 0x7D -#define H_15 0x7E -#define H_16 0x7F - -#define I_1 0x80 -#define I_2 0x81 -#define I_3 0x82 -#define I_4 0x83 -#define I_5 0x84 -#define I_6 0x85 -#define I_7 0x86 -#define I_8 0x87 -#define I_9 0x88 -#define I_10 0x89 -#define I_11 0x8A -#define I_12 0x8B -#define I_13 0x8C -#define I_14 0x8D -#define I_15 0x8E -#define I_16 0x8F - -#define J_1 0x90 -#define J_2 0x91 -#define J_3 0x92 -#define J_4 0x93 -#define J_5 0x94 -#define J_6 0x95 -#define J_7 0x96 -#define J_8 0x97 -#define J_9 0x98 -#define J_10 0x99 -#define J_11 0x9A -#define J_12 0x9B -#define J_13 0x9C -#define J_14 0x9D -#define J_15 0x9E -#define J_16 0x9F - -#define K_1 0xA0 -#define K_2 0xA1 -#define K_3 0xA2 -#define K_4 0xA3 -#define K_5 0xA4 -#define K_6 0xA5 -#define K_7 0xA6 -#define K_8 0xA7 -#define K_9 0xA8 -#define K_10 0xA9 -#define K_11 0xAA -#define K_12 0xAB -#define K_13 0xAC -#define K_14 0xAD -#define K_15 0xAE -#define K_16 0xAF - -#define L_1 0xB0 -#define L_2 0xB1 -#define L_3 0xB2 -#define L_4 0xB3 -#define L_5 0xB4 -#define L_6 0xB5 -#define L_7 0xB6 -#define L_8 0xB7 -#define L_9 0xB8 -#define L_10 0xB9 -#define L_11 0xBA -#define L_12 0xBB -#define L_13 0xBC -#define L_14 0xBD -#define L_15 0xBE -#define L_16 0xBF diff --git a/drivers/issi/is31fl3736.c b/drivers/issi/is31fl3736.c deleted file mode 100644 index 7dece1b1eb..0000000000 --- a/drivers/issi/is31fl3736.c +++ /dev/null @@ -1,269 +0,0 @@ -/* Copyright 2018 Jason Williams (Wilba) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "is31fl3736.h" -#include "i2c_master.h" -#include "wait.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) -// The address will vary depending on your wiring: -// 00 <-> GND -// 01 <-> SCL -// 10 <-> SDA -// 11 <-> VCC -// ADDR1 represents A1:A0 of the 7-bit address. -// ADDR2 represents A3:A2 of the 7-bit address. -// The result is: 0b101(ADDR2)(ADDR1) -#define ISSI_ADDR_DEFAULT 0x50 - -#define ISSI_COMMANDREGISTER 0xFD -#define ISSI_COMMANDREGISTER_WRITELOCK 0xFE -#define ISSI_INTERRUPTMASKREGISTER 0xF0 -#define ISSI_INTERRUPTSTATUSREGISTER 0xF1 - -#define ISSI_PAGE_LEDCONTROL 0x00 // PG0 -#define ISSI_PAGE_PWM 0x01 // PG1 -#define ISSI_PAGE_AUTOBREATH 0x02 // PG2 -#define ISSI_PAGE_FUNCTION 0x03 // PG3 - -#define ISSI_REG_CONFIGURATION 0x00 // PG3 -#define ISSI_REG_GLOBALCURRENT 0x01 // PG3 -#define ISSI_REG_RESET 0x11 // PG3 -#define ISSI_REG_SWPULLUP 0x0F // PG3 -#define ISSI_REG_CSPULLUP 0x10 // PG3 - -#ifndef ISSI_TIMEOUT -# define ISSI_TIMEOUT 100 -#endif - -#ifndef ISSI_PERSISTENCE -# define ISSI_PERSISTENCE 0 -#endif - -// Transfer buffer for TWITransmitData() -uint8_t g_twi_transfer_buffer[20]; - -// These buffers match the IS31FL3736 PWM registers. -// The control buffers match the PG0 LED On/Off registers. -// Storing them like this is optimal for I2C transfers to the registers. -// We could optimize this and take out the unused registers from these -// buffers and the transfers in IS31FL3736_write_pwm_buffer() but it's -// 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}, {0}}; -bool g_led_control_registers_update_required = false; - -void IS31FL3736_write_register(uint8_t addr, uint8_t reg, uint8_t data) { - g_twi_transfer_buffer[0] = reg; - g_twi_transfer_buffer[1] = data; - -#if ISSI_PERSISTENCE > 0 - for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) { - if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT) == 0) break; - } -#else - i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT); -#endif -} - -void IS31FL3736_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer) { - // assumes PG1 is already selected - - // transmit PWM registers in 12 transfers of 16 bytes - // g_twi_transfer_buffer[] is 20 bytes - - // iterate over the pwm_buffer contents at 16 byte intervals - for (int i = 0; i < 192; i += 16) { - g_twi_transfer_buffer[0] = i; - // copy the data from i to i+15 - // device will auto-increment register for data after the first byte - // thus this sets registers 0x00-0x0F, 0x10-0x1F, etc. in one transfer - for (int j = 0; j < 16; j++) { - g_twi_transfer_buffer[1 + j] = pwm_buffer[i + j]; - } - -#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; - } -#else - i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT); -#endif - } -} - -void IS31FL3736_init(uint8_t addr) { - // In order to avoid the LEDs being driven with garbage data - // in the LED driver's PWM registers, shutdown is enabled last. - // Set up the mode and other settings, clear the PWM registers, - // then disable software shutdown. - - // Unlock the command register. - IS31FL3736_write_register(addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); - - // Select PG0 - IS31FL3736_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_LEDCONTROL); - // Turn off all LEDs. - for (int i = 0x00; i <= 0x17; i++) { - IS31FL3736_write_register(addr, i, 0x00); - } - - // Unlock the command register. - IS31FL3736_write_register(addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); - - // Select PG1 - IS31FL3736_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_PWM); - // Set PWM on all LEDs to 0 - // No need to setup Breath registers to PWM as that is the default. - for (int i = 0x00; i <= 0xBF; i++) { - IS31FL3736_write_register(addr, i, 0x00); - } - - // Unlock the command register. - IS31FL3736_write_register(addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); - - // Select PG3 - IS31FL3736_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_FUNCTION); - // Set global current to maximum. - IS31FL3736_write_register(addr, ISSI_REG_GLOBALCURRENT, 0xFF); - // Disable software shutdown. - IS31FL3736_write_register(addr, ISSI_REG_CONFIGURATION, 0x01); - - // Wait 10ms to ensure the device has woken up. - wait_ms(10); -} - -void IS31FL3736_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { - if (index >= 0 && index < DRIVER_LED_TOTAL) { - is31_led led = g_is31_leds[index]; - - 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; - } -} - -void IS31FL3736_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { - for (int i = 0; i < DRIVER_LED_TOTAL; i++) { - IS31FL3736_set_color(i, red, green, blue); - } -} - -void IS31FL3736_set_led_control_register(uint8_t index, bool red, bool green, bool blue) { - is31_led led = g_is31_leds[index]; - - // IS31FL3733 - // The PWM register for a matrix position (0x00 to 0xBF) can be - // divided by 8 to get the LED control register (0x00 to 0x17), - // then mod 8 to get the bit position within that register. - - // IS31FL3736 - // The PWM register for a matrix position (0x00 to 0xBF) is interleaved, so: - // A1=0x00 A2=0x02 A3=0x04 A4=0x06 A5=0x08 A6=0x0A A7=0x0C A8=0x0E - // B1=0x10 B2=0x12 B3=0x14 - // But also, the LED control registers (0x00 to 0x17) are also interleaved, so: - // A1-A4=0x00 A5-A8=0x01 - // So, the same math applies. - - uint8_t control_register_r = led.r / 8; - uint8_t control_register_g = led.g / 8; - uint8_t control_register_b = led.b / 8; - - uint8_t bit_r = led.r % 8; - uint8_t bit_g = led.g % 8; - uint8_t bit_b = led.b % 8; - - if (red) { - g_led_control_registers[led.driver][control_register_r] |= (1 << bit_r); - } else { - g_led_control_registers[led.driver][control_register_r] &= ~(1 << bit_r); - } - if (green) { - g_led_control_registers[led.driver][control_register_g] |= (1 << bit_g); - } else { - g_led_control_registers[led.driver][control_register_g] &= ~(1 << bit_g); - } - if (blue) { - g_led_control_registers[led.driver][control_register_b] |= (1 << bit_b); - } else { - g_led_control_registers[led.driver][control_register_b] &= ~(1 << bit_b); - } - - g_led_control_registers_update_required = true; -} - -void IS31FL3736_mono_set_brightness(int index, uint8_t value) { - if (index >= 0 && index < 96) { - // Index in range 0..95 -> A1..A8, B1..B8, etc. - // Map index 0..95 to registers 0x00..0xBE (interleaved) - uint8_t pwm_register = index * 2; - g_pwm_buffer[0][pwm_register] = value; - g_pwm_buffer_update_required = true; - } -} - -void IS31FL3736_mono_set_brightness_all(uint8_t value) { - for (int i = 0; i < 96; i++) { - IS31FL3736_mono_set_brightness(i, value); - } -} - -void IS31FL3736_mono_set_led_control_register(uint8_t index, bool enabled) { - // Index in range 0..95 -> A1..A8, B1..B8, etc. - - // Map index 0..95 to registers 0x00..0xBE (interleaved) - uint8_t pwm_register = index * 2; - // Map register 0x00..0xBE (interleaved) into control register and bit - uint8_t control_register = pwm_register / 8; - uint8_t bit = pwm_register % 8; - - if (enabled) { - g_led_control_registers[0][control_register] |= (1 << bit); - } else { - g_led_control_registers[0][control_register] &= ~(1 << bit); - } - - g_led_control_registers_update_required = true; -} - -void IS31FL3736_update_pwm_buffers(uint8_t addr1, uint8_t addr2) { - if (g_pwm_buffer_update_required) { - // Firstly we need to unlock the command register and select PG1 - IS31FL3736_write_register(addr1, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); - IS31FL3736_write_register(addr1, ISSI_COMMANDREGISTER, ISSI_PAGE_PWM); - - IS31FL3736_write_pwm_buffer(addr1, g_pwm_buffer[0]); - // IS31FL3736_write_pwm_buffer(addr2, g_pwm_buffer[1]); - } - g_pwm_buffer_update_required = false; -} - -void IS31FL3736_update_led_control_registers(uint8_t addr1, uint8_t addr2) { - if (g_led_control_registers_update_required) { - // Firstly we need to unlock the command register and select PG0 - IS31FL3736_write_register(addr1, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); - IS31FL3736_write_register(addr1, ISSI_COMMANDREGISTER, ISSI_PAGE_LEDCONTROL); - for (int i = 0; i < 24; i++) { - IS31FL3736_write_register(addr1, i, g_led_control_registers[0][i]); - // IS31FL3736_write_register(addr2, i, g_led_control_registers[1][i]); - } - g_led_control_registers_update_required = false; - } -} diff --git a/drivers/issi/is31fl3736.h b/drivers/issi/is31fl3736.h deleted file mode 100644 index e48e31c279..0000000000 --- a/drivers/issi/is31fl3736.h +++ /dev/null @@ -1,168 +0,0 @@ -/* Copyright 2018 Jason Williams (Wilba) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#pragma once - -#include -#include - -// Simple interface option. -// If these aren't defined, just define them to make it compile - -#ifndef DRIVER_COUNT -# define DRIVER_COUNT 2 -#endif - -#ifndef DRIVER_LED_TOTAL -# define DRIVER_LED_TOTAL 96 -#endif - -typedef struct is31_led { - uint8_t driver : 2; - uint8_t r; - uint8_t g; - uint8_t b; -} __attribute__((packed)) is31_led; - -extern const is31_led g_is31_leds[DRIVER_LED_TOTAL]; - -void IS31FL3736_init(uint8_t addr); -void IS31FL3736_write_register(uint8_t addr, uint8_t reg, uint8_t data); -void IS31FL3736_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer); - -void IS31FL3736_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); -void IS31FL3736_set_color_all(uint8_t red, uint8_t green, uint8_t blue); - -void IS31FL3736_set_led_control_register(uint8_t index, bool red, bool green, bool blue); - -void IS31FL3736_mono_set_brightness(int index, uint8_t value); -void IS31FL3736_mono_set_brightness_all(uint8_t value); -void IS31FL3736_mono_set_led_control_register(uint8_t index, bool enabled); - -// This should not be called from an interrupt -// (eg. from a timer interrupt). -// Call this while idle (in between matrix scans). -// If the buffer is dirty, it will update the driver with the buffer. -void IS31FL3736_update_pwm_buffers(uint8_t addr1, uint8_t addr2); -void IS31FL3736_update_led_control_registers(uint8_t addr1, uint8_t addr2); - -#define A_1 0x00 -#define A_2 0x02 -#define A_3 0x04 -#define A_4 0x06 -#define A_5 0x08 -#define A_6 0x0A -#define A_7 0x0C -#define A_8 0x0E - -#define B_1 0x10 -#define B_2 0x12 -#define B_3 0x14 -#define B_4 0x16 -#define B_5 0x18 -#define B_6 0x1A -#define B_7 0x1C -#define B_8 0x1E - -#define C_1 0x20 -#define C_2 0x22 -#define C_3 0x24 -#define C_4 0x26 -#define C_5 0x28 -#define C_6 0x2A -#define C_7 0x2C -#define C_8 0x2E - -#define D_1 0x30 -#define D_2 0x32 -#define D_3 0x34 -#define D_4 0x36 -#define D_5 0x38 -#define D_6 0x3A -#define D_7 0x3C -#define D_8 0x3E - -#define E_1 0x40 -#define E_2 0x42 -#define E_3 0x44 -#define E_4 0x46 -#define E_5 0x48 -#define E_6 0x4A -#define E_7 0x4C -#define E_8 0x4E - -#define F_1 0x50 -#define F_2 0x52 -#define F_3 0x54 -#define F_4 0x56 -#define F_5 0x58 -#define F_6 0x5A -#define F_7 0x5C -#define F_8 0x5E - -#define G_1 0x60 -#define G_2 0x62 -#define G_3 0x64 -#define G_4 0x66 -#define G_5 0x68 -#define G_6 0x6A -#define G_7 0x6C -#define G_8 0x6E - -#define H_1 0x70 -#define H_2 0x72 -#define H_3 0x74 -#define H_4 0x76 -#define H_5 0x78 -#define H_6 0x7A -#define H_7 0x7C -#define H_8 0x7E - -#define I_1 0x80 -#define I_2 0x82 -#define I_3 0x84 -#define I_4 0x86 -#define I_5 0x88 -#define I_6 0x8A -#define I_7 0x8C -#define I_8 0x8E - -#define J_1 0x90 -#define J_2 0x92 -#define J_3 0x94 -#define J_4 0x96 -#define J_5 0x98 -#define J_6 0x9A -#define J_7 0x9C -#define J_8 0x9E - -#define K_1 0xA0 -#define K_2 0xA2 -#define K_3 0xA4 -#define K_4 0xA6 -#define K_5 0xA8 -#define K_6 0xAA -#define K_7 0xAC -#define K_8 0xAE - -#define L_1 0xB0 -#define L_2 0xB2 -#define L_3 0xB4 -#define L_4 0xB6 -#define L_5 0xB8 -#define L_6 0xBA -#define L_7 0xBC -#define L_8 0xBE diff --git a/drivers/issi/is31fl3737.c b/drivers/issi/is31fl3737.c deleted file mode 100644 index 30906b4840..0000000000 --- a/drivers/issi/is31fl3737.c +++ /dev/null @@ -1,227 +0,0 @@ -/* Copyright 2017 Jason Williams - * Copyright 2018 Jack Humbert - * Copyright 2018 Yiancar - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#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) -// The address will vary depending on your wiring: -// 00 <-> GND -// 01 <-> SCL -// 10 <-> SDA -// 11 <-> VCC -// ADDR1 represents A1:A0 of the 7-bit address. -// ADDR2 represents A3:A2 of the 7-bit address. -// The result is: 0b101(ADDR2)(ADDR1) -#define ISSI_ADDR_DEFAULT 0x50 - -#define ISSI_COMMANDREGISTER 0xFD -#define ISSI_COMMANDREGISTER_WRITELOCK 0xFE -#define ISSI_INTERRUPTMASKREGISTER 0xF0 -#define ISSI_INTERRUPTSTATUSREGISTER 0xF1 - -#define ISSI_PAGE_LEDCONTROL 0x00 // PG0 -#define ISSI_PAGE_PWM 0x01 // PG1 -#define ISSI_PAGE_AUTOBREATH 0x02 // PG2 -#define ISSI_PAGE_FUNCTION 0x03 // PG3 - -#define ISSI_REG_CONFIGURATION 0x00 // PG3 -#define ISSI_REG_GLOBALCURRENT 0x01 // PG3 -#define ISSI_REG_RESET 0x11 // PG3 -#define ISSI_REG_SWPULLUP 0x0F // PG3 -#define ISSI_REG_CSPULLUP 0x10 // PG3 - -#ifndef ISSI_TIMEOUT -# define ISSI_TIMEOUT 100 -#endif - -#ifndef ISSI_PERSISTENCE -# define ISSI_PERSISTENCE 0 -#endif - -// Transfer buffer for TWITransmitData() -uint8_t g_twi_transfer_buffer[20]; - -// These buffers match the IS31FL3737 PWM registers. -// The control buffers match the PG0 LED On/Off registers. -// Storing them like this is optimal for I2C transfers to the registers. -// We could optimize this and take out the unused registers from these -// buffers and the transfers in IS31FL3737_write_pwm_buffer() but it's -// probably not worth the extra complexity. - -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; - g_twi_transfer_buffer[1] = data; - -#if ISSI_PERSISTENCE > 0 - for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) { - if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT) == 0) break; - } -#else - i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT); -#endif -} - -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 - // g_twi_transfer_buffer[] is 20 bytes - - // iterate over the pwm_buffer contents at 16 byte intervals - for (int i = 0; i < 192; i += 16) { - g_twi_transfer_buffer[0] = i; - // copy the data from i to i+15 - // device will auto-increment register for data after the first byte - // thus this sets registers 0x00-0x0F, 0x10-0x1F, etc. in one transfer - for (int j = 0; j < 16; j++) { - g_twi_transfer_buffer[1 + j] = pwm_buffer[i + j]; - } - -#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; - } -#else - i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT); -#endif - } -} - -void IS31FL3737_init(uint8_t addr) { - // In order to avoid the LEDs being driven with garbage data - // in the LED driver's PWM registers, shutdown is enabled last. - // Set up the mode and other settings, clear the PWM registers, - // then disable software shutdown. - - // Unlock the command register. - IS31FL3737_write_register(addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); - - // Select PG0 - IS31FL3737_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_LEDCONTROL); - // Turn off all LEDs. - for (int i = 0x00; i <= 0x17; i++) { - IS31FL3737_write_register(addr, i, 0x00); - } - - // Unlock the command register. - IS31FL3737_write_register(addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); - - // Select PG1 - IS31FL3737_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_PWM); - // Set PWM on all LEDs to 0 - // No need to setup Breath registers to PWM as that is the default. - for (int i = 0x00; i <= 0xBF; i++) { - IS31FL3737_write_register(addr, i, 0x00); - } - - // Unlock the command register. - IS31FL3737_write_register(addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); - - // Select PG3 - IS31FL3737_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_FUNCTION); - // Set global current to maximum. - IS31FL3737_write_register(addr, ISSI_REG_GLOBALCURRENT, 0xFF); - // Disable software shutdown. - IS31FL3737_write_register(addr, ISSI_REG_CONFIGURATION, 0x01); - - // Wait 10ms to ensure the device has woken up. - wait_ms(10); -} - -void IS31FL3737_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { - if (index >= 0 && index < DRIVER_LED_TOTAL) { - // copy the led config from progmem to SRAM - is31_led led; - memcpy_P(&led, (&g_is31_leds[index]), sizeof(led)); - - 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[led.driver] = true; - } -} - -void IS31FL3737_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { - for (int i = 0; i < DRIVER_LED_TOTAL; i++) { - IS31FL3737_set_color(i, red, green, blue); - } -} - -void IS31FL3737_set_led_control_register(uint8_t index, bool red, bool green, bool blue) { - // copy the led config from progmem to SRAM - is31_led led; - memcpy_P(&led, (&g_is31_leds[index]), sizeof(led)); - - uint8_t control_register_r = led.r / 8; - uint8_t control_register_g = led.g / 8; - uint8_t control_register_b = led.b / 8; - uint8_t bit_r = led.r % 8; - uint8_t bit_g = led.g % 8; - uint8_t bit_b = led.b % 8; - - if (red) { - g_led_control_registers[led.driver][control_register_r] |= (1 << bit_r); - } else { - g_led_control_registers[led.driver][control_register_r] &= ~(1 << bit_r); - } - if (green) { - g_led_control_registers[led.driver][control_register_g] |= (1 << bit_g); - } else { - g_led_control_registers[led.driver][control_register_g] &= ~(1 << bit_g); - } - if (blue) { - g_led_control_registers[led.driver][control_register_b] |= (1 << bit_b); - } else { - g_led_control_registers[led.driver][control_register_b] &= ~(1 << bit_b); - } - - g_led_control_registers_update_required[led.driver] = true; -} - -void IS31FL3737_update_pwm_buffers(uint8_t addr, uint8_t index) { - if (g_pwm_buffer_update_required[index]) { - // Firstly we need to unlock the command register and select PG1 - IS31FL3737_write_register(addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); - IS31FL3737_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_PWM); - - IS31FL3737_write_pwm_buffer(addr, g_pwm_buffer[index]); - } - g_pwm_buffer_update_required[index] = false; -} - -void IS31FL3737_update_led_control_registers(uint8_t addr, uint8_t index) { - if (g_led_control_registers_update_required[index]) { - // Firstly we need to unlock the command register and select PG0 - IS31FL3737_write_register(addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); - IS31FL3737_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_LEDCONTROL); - for (int i = 0; i < 24; i++) { - IS31FL3737_write_register(addr, i, g_led_control_registers[index][i]); - } - } - g_led_control_registers_update_required[index] = false; -} diff --git a/drivers/issi/is31fl3737.h b/drivers/issi/is31fl3737.h deleted file mode 100644 index a1d2281778..0000000000 --- a/drivers/issi/is31fl3737.h +++ /dev/null @@ -1,203 +0,0 @@ -/* Copyright 2017 Jason Williams - * Copyright 2018 Jack Humbert - * Copyright 2018 Yiancar - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#pragma once - -#include -#include - -typedef struct is31_led { - uint8_t driver : 2; - uint8_t r; - uint8_t g; - uint8_t b; -} __attribute__((packed)) is31_led; - -extern const is31_led g_is31_leds[DRIVER_LED_TOTAL]; - -void IS31FL3737_init(uint8_t addr); -void IS31FL3737_write_register(uint8_t addr, uint8_t reg, uint8_t data); -void IS31FL3737_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer); - -void IS31FL3737_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); -void IS31FL3737_set_color_all(uint8_t red, uint8_t green, uint8_t blue); - -void IS31FL3737_set_led_control_register(uint8_t index, bool red, bool green, bool blue); - -// This should not be called from an interrupt -// (eg. from a timer interrupt). -// Call this while idle (in between matrix scans). -// If the buffer is dirty, it will update the driver with the buffer. -void IS31FL3737_update_pwm_buffers(uint8_t addr1, uint8_t addr2); -void IS31FL3737_update_led_control_registers(uint8_t addr1, uint8_t addr2); - -#define A_1 0x00 -#define A_2 0x01 -#define A_3 0x02 -#define A_4 0x03 -#define A_5 0x04 -#define A_6 0x05 -#define A_7 0x08 -#define A_8 0x09 -#define A_9 0x0A -#define A_10 0x0B -#define A_11 0x0C -#define A_12 0x0D - -#define B_1 0x10 -#define B_2 0x11 -#define B_3 0x12 -#define B_4 0x13 -#define B_5 0x14 -#define B_6 0x15 -#define B_7 0x18 -#define B_8 0x19 -#define B_9 0x1A -#define B_10 0x1B -#define B_11 0x1C -#define B_12 0x1D - -#define C_1 0x20 -#define C_2 0x21 -#define C_3 0x22 -#define C_4 0x23 -#define C_5 0x24 -#define C_6 0x25 -#define C_7 0x28 -#define C_8 0x29 -#define C_9 0x2A -#define C_10 0x2B -#define C_11 0x2C -#define C_12 0x2D - -#define D_1 0x30 -#define D_2 0x31 -#define D_3 0x32 -#define D_4 0x33 -#define D_5 0x34 -#define D_6 0x35 -#define D_7 0x38 -#define D_8 0x39 -#define D_9 0x3A -#define D_10 0x3B -#define D_11 0x3C -#define D_12 0x3D - -#define E_1 0x40 -#define E_2 0x41 -#define E_3 0x42 -#define E_4 0x43 -#define E_5 0x44 -#define E_6 0x45 -#define E_7 0x48 -#define E_8 0x49 -#define E_9 0x4A -#define E_10 0x4B -#define E_11 0x4C -#define E_12 0x4D - -#define F_1 0x50 -#define F_2 0x51 -#define F_3 0x52 -#define F_4 0x53 -#define F_5 0x54 -#define F_6 0x55 -#define F_7 0x58 -#define F_8 0x59 -#define F_9 0x5A -#define F_10 0x5B -#define F_11 0x5C -#define F_12 0x5D - -#define G_1 0x60 -#define G_2 0x61 -#define G_3 0x62 -#define G_4 0x63 -#define G_5 0x64 -#define G_6 0x65 -#define G_7 0x68 -#define G_8 0x69 -#define G_9 0x6A -#define G_10 0x6B -#define G_11 0x6C -#define G_12 0x6D - -#define H_1 0x70 -#define H_2 0x71 -#define H_3 0x72 -#define H_4 0x73 -#define H_5 0x74 -#define H_6 0x75 -#define H_7 0x78 -#define H_8 0x79 -#define H_9 0x7A -#define H_10 0x7B -#define H_11 0x7C -#define H_12 0x7D - -#define I_1 0x80 -#define I_2 0x81 -#define I_3 0x82 -#define I_4 0x83 -#define I_5 0x84 -#define I_6 0x85 -#define I_7 0x88 -#define I_8 0x89 -#define I_9 0x8A -#define I_10 0x8B -#define I_11 0x8C -#define I_12 0x8D - -#define J_1 0x90 -#define J_2 0x91 -#define J_3 0x92 -#define J_4 0x93 -#define J_5 0x94 -#define J_6 0x95 -#define J_7 0x98 -#define J_8 0x99 -#define J_9 0x9A -#define J_10 0x9B -#define J_11 0x9C -#define J_12 0x9D - -#define K_1 0xA0 -#define K_2 0xA1 -#define K_3 0xA2 -#define K_4 0xA3 -#define K_5 0xA4 -#define K_6 0xA5 -#define K_7 0xA8 -#define K_8 0xA9 -#define K_9 0xAA -#define K_10 0xAB -#define K_11 0xAC -#define K_12 0xAD - -#define L_1 0xB0 -#define L_2 0xB1 -#define L_3 0xB2 -#define L_4 0xB3 -#define L_5 0xB4 -#define L_6 0xB5 -#define L_7 0xB8 -#define L_8 0xB9 -#define L_9 0xBA -#define L_10 0xBB -#define L_11 0xBC -#define L_12 0xBD diff --git a/drivers/issi/is31fl3741.c b/drivers/issi/is31fl3741.c deleted file mode 100644 index 1b533c9b6a..0000000000 --- a/drivers/issi/is31fl3741.c +++ /dev/null @@ -1,255 +0,0 @@ -/* Copyright 2017 Jason Williams - * Copyright 2018 Jack Humbert - * Copyright 2018 Yiancar - * Copyright 2020 MelGeek - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "wait.h" - -#include "is31fl3741.h" -#include -#include "i2c_master.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) -// The address will vary depending on your wiring: -// 00 <-> GND -// 01 <-> SCL -// 10 <-> SDA -// 11 <-> VCC -// ADDR1 represents A1:A0 of the 7-bit address. -// ADDR2 represents A3:A2 of the 7-bit address. -// The result is: 0b101(ADDR2)(ADDR1) -#define ISSI_ADDR_DEFAULT 0x60 - -#define ISSI_COMMANDREGISTER 0xFD -#define ISSI_COMMANDREGISTER_WRITELOCK 0xFE -#define ISSI_INTERRUPTMASKREGISTER 0xF0 -#define ISSI_INTERRUPTSTATUSREGISTER 0xF1 -#define ISSI_IDREGISTER 0xFC - -#define ISSI_PAGE_PWM0 0x00 // PG0 -#define ISSI_PAGE_PWM1 0x01 // PG1 -#define ISSI_PAGE_SCALING_0 0x02 // PG2 -#define ISSI_PAGE_SCALING_1 0x03 // PG3 -#define ISSI_PAGE_FUNCTION 0x04 // PG4 - -#define ISSI_REG_CONFIGURATION 0x00 // PG4 -#define ISSI_REG_GLOBALCURRENT 0x01 // PG4 -#define ISSI_REG_PULLDOWNUP 0x02 // PG4 -#define ISSI_REG_RESET 0x3F // PG4 - -#ifndef ISSI_TIMEOUT -# define ISSI_TIMEOUT 100 -#endif - -#ifndef ISSI_PERSISTENCE -# define ISSI_PERSISTENCE 0 -#endif - -#define ISSI_MAX_LEDS 351 - -// Transfer buffer for TWITransmitData() -uint8_t g_twi_transfer_buffer[20] = {0xFF}; - -// These buffers match the IS31FL3741 and IS31FL3741A PWM registers. -// The scaling buffers match the PG2 and PG3 LED On/Off registers. -// Storing them like this is optimal for I2C transfers to the registers. -// We could optimize this and take out the unused registers from these -// buffers and the transfers in IS31FL3741_write_pwm_buffer() but it's -// probably not worth the extra complexity. -uint8_t g_pwm_buffer[DRIVER_COUNT][ISSI_MAX_LEDS]; -bool g_pwm_buffer_update_required = false; -bool g_scaling_registers_update_required[DRIVER_COUNT] = {false}; - -uint8_t g_scaling_registers[DRIVER_COUNT][ISSI_MAX_LEDS]; - -void IS31FL3741_write_register(uint8_t addr, uint8_t reg, uint8_t data) { - g_twi_transfer_buffer[0] = reg; - g_twi_transfer_buffer[1] = data; - -#if ISSI_PERSISTENCE > 0 - for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) { - if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT) == 0) break; - } -#else - i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT); -#endif -} - -bool IS31FL3741_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer) { - // unlock the command register and select PG2 - IS31FL3741_write_register(addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); - IS31FL3741_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_PWM0); - - for (int i = 0; i < 342; i += 18) { - if (i == 180) { - // unlock the command register and select PG2 - IS31FL3741_write_register(addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); - IS31FL3741_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_PWM1); - } - - g_twi_transfer_buffer[0] = i % 180; - memcpy(g_twi_transfer_buffer + 1, pwm_buffer + i, 18); - -#if ISSI_PERSISTENCE > 0 - for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) { - if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 19, ISSI_TIMEOUT) != 0) { - return false; - } - } -#else - if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 19, ISSI_TIMEOUT) != 0) { - return false; - } -#endif - } - - // transfer the left cause the total number is 351 - g_twi_transfer_buffer[0] = 162; - memcpy(g_twi_transfer_buffer + 1, pwm_buffer + 342, 9); - -#if ISSI_PERSISTENCE > 0 - for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) { - if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 10, ISSI_TIMEOUT) != 0) { - return false; - } - } -#else - if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 10, ISSI_TIMEOUT) != 0) { - return false; - } -#endif - - return true; -} - -void IS31FL3741_init(uint8_t addr) { - // In order to avoid the LEDs being driven with garbage data - // in the LED driver's PWM registers, shutdown is enabled last. - // Set up the mode and other settings, clear the PWM registers, - // then disable software shutdown. - // Unlock the command register. - - // Unlock the command register. - IS31FL3741_write_register(addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); - - // Select PG4 - IS31FL3741_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_FUNCTION); - - // Set to Normal operation - IS31FL3741_write_register(addr, ISSI_REG_CONFIGURATION, 0x01); - - // Set Golbal Current Control Register - IS31FL3741_write_register(addr, ISSI_REG_GLOBALCURRENT, 0xFF); - // Set Pull up & Down for SWx CSy - IS31FL3741_write_register(addr, ISSI_REG_PULLDOWNUP, 0x77); - - // IS31FL3741_update_led_scaling_registers(addr, 0xFF, 0xFF, 0xFF); - - // Wait 10ms to ensure the device has woken up. - wait_ms(10); -} - -void IS31FL3741_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { - if (index >= 0 && index < DRIVER_LED_TOTAL) { - is31_led led = g_is31_leds[index]; - - 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; - } -} - -void IS31FL3741_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { - for (int i = 0; i < DRIVER_LED_TOTAL; i++) { - IS31FL3741_set_color(i, red, green, blue); - } -} - -void IS31FL3741_set_led_control_register(uint8_t index, bool red, bool green, bool blue) { - is31_led led = g_is31_leds[index]; - - if (red) { - g_scaling_registers[led.driver][led.r] = 0xFF; - } else { - g_scaling_registers[led.driver][led.r] = 0x00; - } - - if (green) { - g_scaling_registers[led.driver][led.g] = 0xFF; - } else { - g_scaling_registers[led.driver][led.g] = 0x00; - } - - if (blue) { - g_scaling_registers[led.driver][led.b] = 0xFF; - } else { - g_scaling_registers[led.driver][led.b] = 0x00; - } - - g_scaling_registers_update_required[led.driver] = true; -} - -void IS31FL3741_update_pwm_buffers(uint8_t addr1, uint8_t addr2) { - if (g_pwm_buffer_update_required) { - IS31FL3741_write_pwm_buffer(addr1, g_pwm_buffer[0]); - } - - g_pwm_buffer_update_required = false; -} - -void IS31FL3741_set_pwm_buffer(const is31_led *pled, uint8_t red, uint8_t green, uint8_t blue) { - g_pwm_buffer[pled->driver][pled->r] = red; - g_pwm_buffer[pled->driver][pled->g] = green; - g_pwm_buffer[pled->driver][pled->b] = blue; - - g_pwm_buffer_update_required = true; -} - -void IS31FL3741_update_led_control_registers(uint8_t addr, uint8_t index) { - if (g_scaling_registers_update_required[index]) { - // unlock the command register and select PG2 - IS31FL3741_write_register(addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); - IS31FL3741_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_SCALING_0); - - // CS1_SW1 to CS30_SW6 are on PG2 - for (int i = CS1_SW1; i <= CS30_SW6; ++i) { - IS31FL3741_write_register(addr, i, g_scaling_registers[0][i]); - } - - // unlock the command register and select PG3 - IS31FL3741_write_register(addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); - IS31FL3741_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_SCALING_1); - - // CS1_SW7 to CS39_SW9 are on PG3 - for (int i = CS1_SW7; i <= CS39_SW9; ++i) { - IS31FL3741_write_register(addr, i - CS1_SW7, g_scaling_registers[0][i]); - } - - g_scaling_registers_update_required[index] = false; - } -} - -void IS31FL3741_set_scaling_registers(const is31_led *pled, uint8_t red, uint8_t green, uint8_t blue) { - g_scaling_registers[pled->driver][pled->r] = red; - g_scaling_registers[pled->driver][pled->g] = green; - g_scaling_registers[pled->driver][pled->b] = blue; - - g_scaling_registers_update_required[pled->driver] = true; -} diff --git a/drivers/issi/is31fl3741.h b/drivers/issi/is31fl3741.h deleted file mode 100644 index 2df0c5b1a7..0000000000 --- a/drivers/issi/is31fl3741.h +++ /dev/null @@ -1,420 +0,0 @@ -/* Copyright 2017 Jason Williams - * Copyright 2018 Jack Humbert - * Copyright 2018 Yiancar - * Copyright 2020 MelGeek - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#pragma once - -#include -#include - -typedef struct is31_led { - uint32_t driver : 2; - uint32_t r : 10; - uint32_t g : 10; - uint32_t b : 10; -} __attribute__((packed)) is31_led; - -extern const is31_led g_is31_leds[DRIVER_LED_TOTAL]; - -void IS31FL3741_init(uint8_t addr); -void IS31FL3741_write_register(uint8_t addr, uint8_t reg, uint8_t data); -bool IS31FL3741_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer); - -void IS31FL3741_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); -void IS31FL3741_set_color_all(uint8_t red, uint8_t green, uint8_t blue); - -void IS31FL3741_set_led_control_register(uint8_t index, bool red, bool green, bool blue); - -// This should not be called from an interrupt -// (eg. from a timer interrupt). -// Call this while idle (in between matrix scans). -// If the buffer is dirty, it will update the driver with the buffer. -void IS31FL3741_update_pwm_buffers(uint8_t addr1, uint8_t addr2); -void IS31FL3741_update_led_control_registers(uint8_t addr1, uint8_t addr2); -void IS31FL3741_set_scaling_registers(const is31_led *pled, uint8_t red, uint8_t green, uint8_t blue); - -void IS31FL3741_set_pwm_buffer(const is31_led *pled, uint8_t red, uint8_t green, uint8_t blue); - -#define CS1_SW1 0x00 -#define CS2_SW1 0x01 -#define CS3_SW1 0x02 -#define CS4_SW1 0x03 -#define CS5_SW1 0x04 -#define CS6_SW1 0x05 -#define CS7_SW1 0x06 -#define CS8_SW1 0x07 -#define CS9_SW1 0x08 -#define CS10_SW1 0x09 -#define CS11_SW1 0x0A -#define CS12_SW1 0x0B -#define CS13_SW1 0x0C -#define CS14_SW1 0x0D -#define CS15_SW1 0x0E -#define CS16_SW1 0x0F -#define CS17_SW1 0x10 -#define CS18_SW1 0x11 -#define CS19_SW1 0x12 -#define CS20_SW1 0x13 -#define CS21_SW1 0x14 -#define CS22_SW1 0x15 -#define CS23_SW1 0x16 -#define CS24_SW1 0x17 -#define CS25_SW1 0x18 -#define CS26_SW1 0x19 -#define CS27_SW1 0x1A -#define CS28_SW1 0x1B -#define CS29_SW1 0x1C -#define CS30_SW1 0x1D - -#define CS1_SW2 0x1E -#define CS2_SW2 0x1F -#define CS3_SW2 0x20 -#define CS4_SW2 0x21 -#define CS5_SW2 0x22 -#define CS6_SW2 0x23 -#define CS7_SW2 0x24 -#define CS8_SW2 0x25 -#define CS9_SW2 0x26 -#define CS10_SW2 0x27 -#define CS11_SW2 0x28 -#define CS12_SW2 0x29 -#define CS13_SW2 0x2A -#define CS14_SW2 0x2B -#define CS15_SW2 0x2C -#define CS16_SW2 0x2D -#define CS17_SW2 0x2E -#define CS18_SW2 0x2F -#define CS19_SW2 0x30 -#define CS20_SW2 0x31 -#define CS21_SW2 0x32 -#define CS22_SW2 0x33 -#define CS23_SW2 0x34 -#define CS24_SW2 0x35 -#define CS25_SW2 0x36 -#define CS26_SW2 0x37 -#define CS27_SW2 0x38 -#define CS28_SW2 0x39 -#define CS29_SW2 0x3A -#define CS30_SW2 0x3B - -#define CS1_SW3 0x3C -#define CS2_SW3 0x3D -#define CS3_SW3 0x3E -#define CS4_SW3 0x3F -#define CS5_SW3 0x40 -#define CS6_SW3 0x41 -#define CS7_SW3 0x42 -#define CS8_SW3 0x43 -#define CS9_SW3 0x44 -#define CS10_SW3 0x45 -#define CS11_SW3 0x46 -#define CS12_SW3 0x47 -#define CS13_SW3 0x48 -#define CS14_SW3 0x49 -#define CS15_SW3 0x4A -#define CS16_SW3 0x4B -#define CS17_SW3 0x4C -#define CS18_SW3 0x4D -#define CS19_SW3 0x4E -#define CS20_SW3 0x4F -#define CS21_SW3 0x50 -#define CS22_SW3 0x51 -#define CS23_SW3 0x52 -#define CS24_SW3 0x53 -#define CS25_SW3 0x54 -#define CS26_SW3 0x55 -#define CS27_SW3 0x56 -#define CS28_SW3 0x57 -#define CS29_SW3 0x58 -#define CS30_SW3 0x59 - -#define CS1_SW4 0x5A -#define CS2_SW4 0x5B -#define CS3_SW4 0x5C -#define CS4_SW4 0x5D -#define CS5_SW4 0x5E -#define CS6_SW4 0x5F -#define CS7_SW4 0x60 -#define CS8_SW4 0x61 -#define CS9_SW4 0x62 -#define CS10_SW4 0x63 -#define CS11_SW4 0x64 -#define CS12_SW4 0x65 -#define CS13_SW4 0x66 -#define CS14_SW4 0x67 -#define CS15_SW4 0x68 -#define CS16_SW4 0x69 -#define CS17_SW4 0x6A -#define CS18_SW4 0x6B -#define CS19_SW4 0x6C -#define CS20_SW4 0x6D -#define CS21_SW4 0x6E -#define CS22_SW4 0x6F -#define CS23_SW4 0x70 -#define CS24_SW4 0x71 -#define CS25_SW4 0x72 -#define CS26_SW4 0x73 -#define CS27_SW4 0x74 -#define CS28_SW4 0x75 -#define CS29_SW4 0x76 -#define CS30_SW4 0x77 - -#define CS1_SW5 0x78 -#define CS2_SW5 0x79 -#define CS3_SW5 0x7A -#define CS4_SW5 0x7B -#define CS5_SW5 0x7C -#define CS6_SW5 0x7D -#define CS7_SW5 0x7E -#define CS8_SW5 0x7F -#define CS9_SW5 0x80 -#define CS10_SW5 0x81 -#define CS11_SW5 0x82 -#define CS12_SW5 0x83 -#define CS13_SW5 0x84 -#define CS14_SW5 0x85 -#define CS15_SW5 0x86 -#define CS16_SW5 0x87 -#define CS17_SW5 0x88 -#define CS18_SW5 0x89 -#define CS19_SW5 0x8A -#define CS20_SW5 0x8B -#define CS21_SW5 0x8C -#define CS22_SW5 0x8D -#define CS23_SW5 0x8E -#define CS24_SW5 0x8F -#define CS25_SW5 0x90 -#define CS26_SW5 0x91 -#define CS27_SW5 0x92 -#define CS28_SW5 0x93 -#define CS29_SW5 0x94 -#define CS30_SW5 0x95 - -#define CS1_SW6 0x96 -#define CS2_SW6 0x97 -#define CS3_SW6 0x98 -#define CS4_SW6 0x99 -#define CS5_SW6 0x9A -#define CS6_SW6 0x9B -#define CS7_SW6 0x9C -#define CS8_SW6 0x9D -#define CS9_SW6 0x9E -#define CS10_SW6 0x9F -#define CS11_SW6 0xA0 -#define CS12_SW6 0xA1 -#define CS13_SW6 0xA2 -#define CS14_SW6 0xA3 -#define CS15_SW6 0xA4 -#define CS16_SW6 0xA5 -#define CS17_SW6 0xA6 -#define CS18_SW6 0xA7 -#define CS19_SW6 0xA8 -#define CS20_SW6 0xA9 -#define CS21_SW6 0xAA -#define CS22_SW6 0xAB -#define CS23_SW6 0xAC -#define CS24_SW6 0xAD -#define CS25_SW6 0xAE -#define CS26_SW6 0xAF -#define CS27_SW6 0xB0 -#define CS28_SW6 0xB1 -#define CS29_SW6 0xB2 -#define CS30_SW6 0xB3 - -#define CS1_SW7 0xB4 -#define CS2_SW7 0xB5 -#define CS3_SW7 0xB6 -#define CS4_SW7 0xB7 -#define CS5_SW7 0xB8 -#define CS6_SW7 0xB9 -#define CS7_SW7 0xBA -#define CS8_SW7 0xBB -#define CS9_SW7 0xBC -#define CS10_SW7 0xBD -#define CS11_SW7 0xBE -#define CS12_SW7 0xBF -#define CS13_SW7 0xC0 -#define CS14_SW7 0xC1 -#define CS15_SW7 0xC2 -#define CS16_SW7 0xC3 -#define CS17_SW7 0xC4 -#define CS18_SW7 0xC5 -#define CS19_SW7 0xC6 -#define CS20_SW7 0xC7 -#define CS21_SW7 0xC8 -#define CS22_SW7 0xC9 -#define CS23_SW7 0xCA -#define CS24_SW7 0xCB -#define CS25_SW7 0xCC -#define CS26_SW7 0xCD -#define CS27_SW7 0xCE -#define CS28_SW7 0xCF -#define CS29_SW7 0xD0 -#define CS30_SW7 0xD1 - -#define CS1_SW8 0xD2 -#define CS2_SW8 0xD3 -#define CS3_SW8 0xD4 -#define CS4_SW8 0xD5 -#define CS5_SW8 0xD6 -#define CS6_SW8 0xD7 -#define CS7_SW8 0xD8 -#define CS8_SW8 0xD9 -#define CS9_SW8 0xDA -#define CS10_SW8 0xDB -#define CS11_SW8 0xDC -#define CS12_SW8 0xDD -#define CS13_SW8 0xDE -#define CS14_SW8 0xDF -#define CS15_SW8 0xE0 -#define CS16_SW8 0xE1 -#define CS17_SW8 0xE2 -#define CS18_SW8 0xE3 -#define CS19_SW8 0xE4 -#define CS20_SW8 0xE5 -#define CS21_SW8 0xE6 -#define CS22_SW8 0xE7 -#define CS23_SW8 0xE8 -#define CS24_SW8 0xE9 -#define CS25_SW8 0xEA -#define CS26_SW8 0xEB -#define CS27_SW8 0xEC -#define CS28_SW8 0xED -#define CS29_SW8 0xEE -#define CS30_SW8 0xEF - -#define CS1_SW9 0xF0 -#define CS2_SW9 0xF1 -#define CS3_SW9 0xF2 -#define CS4_SW9 0xF3 -#define CS5_SW9 0xF4 -#define CS6_SW9 0xF5 -#define CS7_SW9 0xF6 -#define CS8_SW9 0xF7 -#define CS9_SW9 0xF8 -#define CS10_SW9 0xF9 -#define CS11_SW9 0xFA -#define CS12_SW9 0xFB -#define CS13_SW9 0xFC -#define CS14_SW9 0xFD -#define CS15_SW9 0xFE -#define CS16_SW9 0xFF -#define CS17_SW9 0x100 -#define CS18_SW9 0x101 -#define CS19_SW9 0x102 -#define CS20_SW9 0x103 -#define CS21_SW9 0x104 -#define CS22_SW9 0x105 -#define CS23_SW9 0x106 -#define CS24_SW9 0x107 -#define CS25_SW9 0x108 -#define CS26_SW9 0x109 -#define CS27_SW9 0x10A -#define CS28_SW9 0x10B -#define CS29_SW9 0x10C -#define CS30_SW9 0x10D - -#define CS31_SW1 0x10E -#define CS32_SW1 0x10F -#define CS33_SW1 0x110 -#define CS34_SW1 0x111 -#define CS35_SW1 0x112 -#define CS36_SW1 0x113 -#define CS37_SW1 0x114 -#define CS38_SW1 0x115 -#define CS39_SW1 0x116 - -#define CS31_SW2 0x117 -#define CS32_SW2 0x118 -#define CS33_SW2 0x119 -#define CS34_SW2 0x11A -#define CS35_SW2 0x11B -#define CS36_SW2 0x11C -#define CS37_SW2 0x11D -#define CS38_SW2 0x11E -#define CS39_SW2 0x11F - -#define CS31_SW3 0x120 -#define CS32_SW3 0x121 -#define CS33_SW3 0x122 -#define CS34_SW3 0x123 -#define CS35_SW3 0x124 -#define CS36_SW3 0x125 -#define CS37_SW3 0x126 -#define CS38_SW3 0x127 -#define CS39_SW3 0x128 - -#define CS31_SW4 0x129 -#define CS32_SW4 0x12A -#define CS33_SW4 0x12B -#define CS34_SW4 0x12C -#define CS35_SW4 0x12D -#define CS36_SW4 0x12E -#define CS37_SW4 0x12F -#define CS38_SW4 0x130 -#define CS39_SW4 0x131 - -#define CS31_SW5 0x132 -#define CS32_SW5 0x133 -#define CS33_SW5 0x134 -#define CS34_SW5 0x135 -#define CS35_SW5 0x136 -#define CS36_SW5 0x137 -#define CS37_SW5 0x138 -#define CS38_SW5 0x139 -#define CS39_SW5 0x13A - -#define CS31_SW6 0x13B -#define CS32_SW6 0x13C -#define CS33_SW6 0x13D -#define CS34_SW6 0x13E -#define CS35_SW6 0x13F -#define CS36_SW6 0x140 -#define CS37_SW6 0x141 -#define CS38_SW6 0x142 -#define CS39_SW6 0x143 - -#define CS31_SW7 0x144 -#define CS32_SW7 0x145 -#define CS33_SW7 0x146 -#define CS34_SW7 0x147 -#define CS35_SW7 0x148 -#define CS36_SW7 0x149 -#define CS37_SW7 0x14A -#define CS38_SW7 0x14B -#define CS39_SW7 0x14C - -#define CS31_SW8 0x14D -#define CS32_SW8 0x14E -#define CS33_SW8 0x14F -#define CS34_SW8 0x150 -#define CS35_SW8 0x151 -#define CS36_SW8 0x152 -#define CS37_SW8 0x153 -#define CS38_SW8 0x154 -#define CS39_SW8 0x155 - -#define CS31_SW9 0x156 -#define CS32_SW9 0x157 -#define CS33_SW9 0x158 -#define CS34_SW9 0x159 -#define CS35_SW9 0x15A -#define CS36_SW9 0x15B -#define CS37_SW9 0x15C -#define CS38_SW9 0x15D -#define CS39_SW9 0x15E diff --git a/drivers/led/apa102.c b/drivers/led/apa102.c new file mode 100644 index 0000000000..7396dc3c55 --- /dev/null +++ b/drivers/led/apa102.c @@ -0,0 +1,151 @@ +/* Copyright 2020 Aldehir Rojas + * Copyright 2017 Mikkel (Duckle29) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "apa102.h" +#include "quantum.h" + +#ifndef APA102_NOPS +# if defined(__AVR__) +# define APA102_NOPS 0 // AVR at 16 MHz already spends 62.5 ns per clock, so no extra delay is needed +# elif defined(PROTOCOL_CHIBIOS) + +# include "hal.h" +# if defined(STM32F0XX) || defined(STM32F1XX) || defined(STM32F3XX) || defined(STM32F4XX) || defined(STM32L0XX) +# define APA102_NOPS (100 / (1000000000L / (STM32_SYSCLK / 4))) // This calculates how many loops of 4 nops to run to delay 100 ns +# else +# error("APA102_NOPS configuration required") +# define APA102_NOPS 0 // this just pleases the compile so the above error is easier to spot +# endif +# endif +#endif + +#define io_wait \ + do { \ + for (int i = 0; i < APA102_NOPS; i++) { \ + __asm__ volatile("nop\n\t" \ + "nop\n\t" \ + "nop\n\t" \ + "nop\n\t"); \ + } \ + } while (0) + +#define APA102_SEND_BIT(byte, bit) \ + do { \ + writePin(RGB_DI_PIN, (byte >> bit) & 1); \ + io_wait; \ + writePinHigh(RGB_CI_PIN); \ + io_wait; \ + writePinLow(RGB_CI_PIN); \ + io_wait; \ + } while (0) + +uint8_t apa102_led_brightness = APA102_DEFAULT_BRIGHTNESS; + +void static apa102_start_frame(void); +void static apa102_end_frame(uint16_t num_leds); + +void static apa102_send_frame(uint8_t red, uint8_t green, uint8_t blue, uint8_t brightness); +void static apa102_send_byte(uint8_t byte); + +void apa102_setleds(LED_TYPE *start_led, uint16_t num_leds) { + LED_TYPE *end = start_led + num_leds; + + apa102_start_frame(); + for (LED_TYPE *led = start_led; led < end; led++) { + apa102_send_frame(led->r, led->g, led->b, apa102_led_brightness); + } + apa102_end_frame(num_leds); +} + +// Overwrite the default rgblight_call_driver to use apa102 driver +void rgblight_call_driver(LED_TYPE *start_led, uint8_t num_leds) { apa102_setleds(start_led, num_leds); } + +void static apa102_init(void) { + setPinOutput(RGB_DI_PIN); + setPinOutput(RGB_CI_PIN); + + writePinLow(RGB_DI_PIN); + writePinLow(RGB_CI_PIN); +} + +void apa102_set_brightness(uint8_t brightness) { + if (brightness > APA102_MAX_BRIGHTNESS) { + apa102_led_brightness = APA102_MAX_BRIGHTNESS; + } else if (brightness < 0) { + apa102_led_brightness = 0; + } else { + apa102_led_brightness = brightness; + } +} + +void static apa102_send_frame(uint8_t red, uint8_t green, uint8_t blue, uint8_t brightness) { + apa102_send_byte(0b11100000 | brightness); + apa102_send_byte(blue); + apa102_send_byte(green); + apa102_send_byte(red); +} + +void static apa102_start_frame(void) { + apa102_init(); + for (uint16_t i = 0; i < 4; i++) { + apa102_send_byte(0); + } +} + +void static apa102_end_frame(uint16_t num_leds) { + // This function has been taken from: https://github.com/pololu/apa102-arduino/blob/master/APA102.h + // and adapted. The code is MIT licensed. I think thats compatible? + // + // The data stream seen by the last LED in the chain will be delayed by + // (count - 1) clock edges, because each LED before it inverts the clock + // line and delays the data by one clock edge. Therefore, to make sure + // the last LED actually receives the data we wrote, the number of extra + // edges we send at the end of the frame must be at least (count - 1). + // + // Assuming we only want to send these edges in groups of size K, the + // C/C++ expression for the minimum number of groups to send is: + // + // ((count - 1) + (K - 1)) / K + // + // The C/C++ expression above is just (count - 1) divided by K, + // rounded up to the nearest whole number if there is a remainder. + // + // We set K to 16 and use the formula above as the number of frame-end + // bytes to transfer. Each byte has 16 clock edges. + // + // We are ignoring the specification for the end frame in the APA102 + // datasheet, which says to send 0xFF four times, because it does not work + // when you have 66 LEDs or more, and also it results in unwanted white + // pixels if you try to update fewer LEDs than are on your LED strip. + uint16_t iterations = (num_leds + 14) / 16; + for (uint16_t i = 0; i < iterations; i++) { + apa102_send_byte(0); + } + + apa102_init(); +} + +void static apa102_send_byte(uint8_t byte) { + APA102_SEND_BIT(byte, 7); + APA102_SEND_BIT(byte, 6); + APA102_SEND_BIT(byte, 5); + APA102_SEND_BIT(byte, 4); + APA102_SEND_BIT(byte, 3); + APA102_SEND_BIT(byte, 2); + APA102_SEND_BIT(byte, 1); + APA102_SEND_BIT(byte, 0); +} diff --git a/drivers/led/apa102.h b/drivers/led/apa102.h new file mode 100644 index 0000000000..58cf020c1e --- /dev/null +++ b/drivers/led/apa102.h @@ -0,0 +1,41 @@ +/* Copyright 2020 Aldehir Rojas + * Copyright 2017 Mikkel (Duckle29) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include "color.h" + +#ifndef APA102_DEFAULT_BRIGHTNESS +# define APA102_DEFAULT_BRIGHTNESS 31 +#endif + +#define APA102_MAX_BRIGHTNESS 31 + +extern uint8_t apa102_led_brightness; + +/* User Interface + * + * Input: + * start_led: An array of GRB data describing the LED colors + * num_leds: The number of LEDs to write + * + * The functions will perform the following actions: + * - Set the data-out pin as output + * - Send out the LED data + */ +void apa102_setleds(LED_TYPE *start_led, uint16_t num_leds); +void apa102_set_brightness(uint8_t brightness); diff --git a/drivers/led/aw20216.c b/drivers/led/aw20216.c new file mode 100644 index 0000000000..c608c0ab44 --- /dev/null +++ b/drivers/led/aw20216.c @@ -0,0 +1,141 @@ +/* Copyright 2021 Jasper Chan + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "aw20216.h" +#include "spi_master.h" + +/* The AW20216 appears to be somewhat similar to the IS31FL743, although quite + * a few things are different, such as the command byte format and page ordering. + * The LED addresses start from 0x00 instead of 0x01. + */ +#define AWINIC_ID 0b1010 << 4 + +#define AW_PAGE_FUNCTION 0x00 << 1 // PG0, Function registers +#define AW_PAGE_PWM 0x01 << 1 // PG1, LED PWM control +#define AW_PAGE_SCALING 0x02 << 1 // PG2, LED current scaling control +#define AW_PAGE_PATCHOICE 0x03 << 1 // PG3, Pattern choice? +#define AW_PAGE_PWMSCALING 0x04 << 1 // PG4, LED PWM + Scaling control? + +#define AW_WRITE 0 +#define AW_READ 1 + +#define AW_REG_CONFIGURATION 0x00 // PG0 +#define AW_REG_GLOBALCURRENT 0x01 // PG0 + +// Default value of AW_REG_CONFIGURATION +// D7:D4 = 1011, SWSEL (SW1~SW12 active) +// D3 = 0?, reserved (apparently this should be 1 but it doesn't seem to matter) +// D2:D1 = 00, OSDE (open/short detection enable) +// D0 = 0, CHIPEN (write 1 to enable LEDs when hardware enable pulled high) +#define AW_CONFIG_DEFAULT 0b10110000 +#define AW_CHIPEN 1 + +#define AW_PWM_REGISTER_COUNT 216 + +#ifndef AW_SCALING_MAX +# define AW_SCALING_MAX 150 +#endif + +#ifndef AW_GLOBAL_CURRENT_MAX +# define AW_GLOBAL_CURRENT_MAX 150 +#endif + +#ifndef AW_SPI_DIVISOR +# define AW_SPI_DIVISOR 4 +#endif + +uint8_t g_pwm_buffer[DRIVER_COUNT][AW_PWM_REGISTER_COUNT]; +bool g_pwm_buffer_update_required[DRIVER_COUNT] = {false}; + +bool AW20216_write(pin_t cs_pin, uint8_t page, uint8_t reg, uint8_t* data, uint8_t len) { + static uint8_t s_spi_transfer_buffer[2] = {0}; + + if (!spi_start(cs_pin, false, 0, AW_SPI_DIVISOR)) { + spi_stop(); + return false; + } + + s_spi_transfer_buffer[0] = (AWINIC_ID | page | AW_WRITE); + s_spi_transfer_buffer[1] = reg; + + if (spi_transmit(s_spi_transfer_buffer, 2) != SPI_STATUS_SUCCESS) { + spi_stop(); + return false; + } + + if (spi_transmit(data, len) != SPI_STATUS_SUCCESS) { + spi_stop(); + return false; + } + + spi_stop(); + return true; +} + +static inline bool AW20216_write_register(pin_t cs_pin, uint8_t page, uint8_t reg, uint8_t value) { + // Little wrapper so callers need not care about sending a buffer + return AW20216_write(cs_pin, page, reg, &value, 1); +} + +static void AW20216_init_scaling(pin_t cs_pin) { + // Set constant current to the max, control brightness with PWM + for (uint8_t i = 0; i < AW_PWM_REGISTER_COUNT; i++) { + AW20216_write_register(cs_pin, AW_PAGE_SCALING, i, AW_SCALING_MAX); + } +} + +static inline void AW20216_init_current_limit(pin_t cs_pin) { + // Push config + AW20216_write_register(cs_pin, AW_PAGE_FUNCTION, AW_REG_GLOBALCURRENT, AW_GLOBAL_CURRENT_MAX); +} + +static inline void AW20216_soft_enable(pin_t cs_pin) { + // Push config + AW20216_write_register(cs_pin, AW_PAGE_FUNCTION, AW_REG_CONFIGURATION, AW_CONFIG_DEFAULT | AW_CHIPEN); +} + +void AW20216_init(pin_t cs_pin, pin_t en_pin) { + setPinOutput(en_pin); + writePinHigh(en_pin); + + // Drivers should start with all scaling and PWM registers as off + AW20216_init_current_limit(cs_pin); + AW20216_init_scaling(cs_pin); + + AW20216_soft_enable(cs_pin); +} + +void AW20216_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { + aw_led led = g_aw_leds[index]; + + 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[led.driver] = true; +} + +void AW20216_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { + for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) { + AW20216_set_color(i, red, green, blue); + } +} + +void AW20216_update_pwm_buffers(pin_t cs_pin, uint8_t index) { + if (g_pwm_buffer_update_required[index]) { + AW20216_write(cs_pin, AW_PAGE_PWM, 0, g_pwm_buffer[index], AW_PWM_REGISTER_COUNT); + } + g_pwm_buffer_update_required[index] = false; +} diff --git a/drivers/led/aw20216.h b/drivers/led/aw20216.h new file mode 100644 index 0000000000..c55d9605fc --- /dev/null +++ b/drivers/led/aw20216.h @@ -0,0 +1,252 @@ +/* Copyright 2021 Jasper Chan (Gigahawk) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include +#include +#include "gpio.h" + +typedef struct aw_led { + uint8_t driver : 2; + uint8_t r; + uint8_t g; + uint8_t b; +} aw_led; + +extern const aw_led g_aw_leds[DRIVER_LED_TOTAL]; + +void AW20216_init(pin_t cs_pin, pin_t en_pin); +void AW20216_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); +void AW20216_set_color_all(uint8_t red, uint8_t green, uint8_t blue); +void AW20216_update_pwm_buffers(pin_t cs_pin, uint8_t index); + +#define CS1_SW1 0x00 +#define CS2_SW1 0x01 +#define CS3_SW1 0x02 +#define CS4_SW1 0x03 +#define CS5_SW1 0x04 +#define CS6_SW1 0x05 +#define CS7_SW1 0x06 +#define CS8_SW1 0x07 +#define CS9_SW1 0x08 +#define CS10_SW1 0x09 +#define CS11_SW1 0x0A +#define CS12_SW1 0x0B +#define CS13_SW1 0x0C +#define CS14_SW1 0x0D +#define CS15_SW1 0x0E +#define CS16_SW1 0x0F +#define CS17_SW1 0x10 +#define CS18_SW1 0x11 +#define CS1_SW2 0x12 +#define CS2_SW2 0x13 +#define CS3_SW2 0x14 +#define CS4_SW2 0x15 +#define CS5_SW2 0x16 +#define CS6_SW2 0x17 +#define CS7_SW2 0x18 +#define CS8_SW2 0x19 +#define CS9_SW2 0x1A +#define CS10_SW2 0x1B +#define CS11_SW2 0x1C +#define CS12_SW2 0x1D +#define CS13_SW2 0x1E +#define CS14_SW2 0x1F +#define CS15_SW2 0x20 +#define CS16_SW2 0x21 +#define CS17_SW2 0x22 +#define CS18_SW2 0x23 +#define CS1_SW3 0x24 +#define CS2_SW3 0x25 +#define CS3_SW3 0x26 +#define CS4_SW3 0x27 +#define CS5_SW3 0x28 +#define CS6_SW3 0x29 +#define CS7_SW3 0x2A +#define CS8_SW3 0x2B +#define CS9_SW3 0x2C +#define CS10_SW3 0x2D +#define CS11_SW3 0x2E +#define CS12_SW3 0x2F +#define CS13_SW3 0x30 +#define CS14_SW3 0x31 +#define CS15_SW3 0x32 +#define CS16_SW3 0x33 +#define CS17_SW3 0x34 +#define CS18_SW3 0x35 +#define CS1_SW4 0x36 +#define CS2_SW4 0x37 +#define CS3_SW4 0x38 +#define CS4_SW4 0x39 +#define CS5_SW4 0x3A +#define CS6_SW4 0x3B +#define CS7_SW4 0x3C +#define CS8_SW4 0x3D +#define CS9_SW4 0x3E +#define CS10_SW4 0x3F +#define CS11_SW4 0x40 +#define CS12_SW4 0x41 +#define CS13_SW4 0x42 +#define CS14_SW4 0x43 +#define CS15_SW4 0x44 +#define CS16_SW4 0x45 +#define CS17_SW4 0x46 +#define CS18_SW4 0x47 +#define CS1_SW5 0x48 +#define CS2_SW5 0x49 +#define CS3_SW5 0x4A +#define CS4_SW5 0x4B +#define CS5_SW5 0x4C +#define CS6_SW5 0x4D +#define CS7_SW5 0x4E +#define CS8_SW5 0x4F +#define CS9_SW5 0x50 +#define CS10_SW5 0x51 +#define CS11_SW5 0x52 +#define CS12_SW5 0x53 +#define CS13_SW5 0x54 +#define CS14_SW5 0x55 +#define CS15_SW5 0x56 +#define CS16_SW5 0x57 +#define CS17_SW5 0x58 +#define CS18_SW5 0x59 +#define CS1_SW6 0x5A +#define CS2_SW6 0x5B +#define CS3_SW6 0x5C +#define CS4_SW6 0x5D +#define CS5_SW6 0x5E +#define CS6_SW6 0x5F +#define CS7_SW6 0x60 +#define CS8_SW6 0x61 +#define CS9_SW6 0x62 +#define CS10_SW6 0x63 +#define CS11_SW6 0x64 +#define CS12_SW6 0x65 +#define CS13_SW6 0x66 +#define CS14_SW6 0x67 +#define CS15_SW6 0x68 +#define CS16_SW6 0x69 +#define CS17_SW6 0x6A +#define CS18_SW6 0x6B +#define CS1_SW7 0x6C +#define CS2_SW7 0x6D +#define CS3_SW7 0x6E +#define CS4_SW7 0x6F +#define CS5_SW7 0x70 +#define CS6_SW7 0x71 +#define CS7_SW7 0x72 +#define CS8_SW7 0x73 +#define CS9_SW7 0x74 +#define CS10_SW7 0x75 +#define CS11_SW7 0x76 +#define CS12_SW7 0x77 +#define CS13_SW7 0x78 +#define CS14_SW7 0x79 +#define CS15_SW7 0x7A +#define CS16_SW7 0x7B +#define CS17_SW7 0x7C +#define CS18_SW7 0x7D +#define CS1_SW8 0x7E +#define CS2_SW8 0x7F +#define CS3_SW8 0x80 +#define CS4_SW8 0x81 +#define CS5_SW8 0x82 +#define CS6_SW8 0x83 +#define CS7_SW8 0x84 +#define CS8_SW8 0x85 +#define CS9_SW8 0x86 +#define CS10_SW8 0x87 +#define CS11_SW8 0x88 +#define CS12_SW8 0x89 +#define CS13_SW8 0x8A +#define CS14_SW8 0x8B +#define CS15_SW8 0x8C +#define CS16_SW8 0x8D +#define CS17_SW8 0x8E +#define CS18_SW8 0x8F +#define CS1_SW9 0x90 +#define CS2_SW9 0x91 +#define CS3_SW9 0x92 +#define CS4_SW9 0x93 +#define CS5_SW9 0x94 +#define CS6_SW9 0x95 +#define CS7_SW9 0x96 +#define CS8_SW9 0x97 +#define CS9_SW9 0x98 +#define CS10_SW9 0x99 +#define CS11_SW9 0x9A +#define CS12_SW9 0x9B +#define CS13_SW9 0x9C +#define CS14_SW9 0x9D +#define CS15_SW9 0x9E +#define CS16_SW9 0x9F +#define CS17_SW9 0xA0 +#define CS18_SW9 0xA1 +#define CS1_SW10 0xA2 +#define CS2_SW10 0xA3 +#define CS3_SW10 0xA4 +#define CS4_SW10 0xA5 +#define CS5_SW10 0xA6 +#define CS6_SW10 0xA7 +#define CS7_SW10 0xA8 +#define CS8_SW10 0xA9 +#define CS9_SW10 0xAA +#define CS10_SW10 0xAB +#define CS11_SW10 0xAC +#define CS12_SW10 0xAD +#define CS13_SW10 0xAE +#define CS14_SW10 0xAF +#define CS15_SW10 0xB0 +#define CS16_SW10 0xB1 +#define CS17_SW10 0xB2 +#define CS18_SW10 0xB3 +#define CS1_SW11 0xB4 +#define CS2_SW11 0xB5 +#define CS3_SW11 0xB6 +#define CS4_SW11 0xB7 +#define CS5_SW11 0xB8 +#define CS6_SW11 0xB9 +#define CS7_SW11 0xBA +#define CS8_SW11 0xBB +#define CS9_SW11 0xBC +#define CS10_SW11 0xBD +#define CS11_SW11 0xBE +#define CS12_SW11 0xBF +#define CS13_SW11 0xC0 +#define CS14_SW11 0xC1 +#define CS15_SW11 0xC2 +#define CS16_SW11 0xC3 +#define CS17_SW11 0xC4 +#define CS18_SW11 0xC5 +#define CS1_SW12 0xC6 +#define CS2_SW12 0xC7 +#define CS3_SW12 0xC8 +#define CS4_SW12 0xC9 +#define CS5_SW12 0xCA +#define CS6_SW12 0xCB +#define CS7_SW12 0xCC +#define CS8_SW12 0xCD +#define CS9_SW12 0xCE +#define CS10_SW12 0xCF +#define CS11_SW12 0xD0 +#define CS12_SW12 0xD1 +#define CS13_SW12 0xD2 +#define CS14_SW12 0xD3 +#define CS15_SW12 0xD4 +#define CS16_SW12 0xD5 +#define CS17_SW12 0xD6 +#define CS18_SW12 0xD7 diff --git a/drivers/led/issi/is31fl3218.c b/drivers/led/issi/is31fl3218.c new file mode 100644 index 0000000000..d43863ac4b --- /dev/null +++ b/drivers/led/issi/is31fl3218.c @@ -0,0 +1,96 @@ +/* Copyright 2018 Jason Williams (Wilba) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include "is31fl3218.h" +#include "i2c_master.h" + +// This is the full 8-bit address +#define ISSI_ADDRESS 0b10101000 + +// These are the register addresses +#define ISSI_REG_SHUTDOWN 0x00 +#define ISSI_REG_PWM 0x01 +#define ISSI_REG_CONTROL 0x13 +#define ISSI_REG_UPDATE 0x16 +#define ISSI_REG_RESET 0x17 + +// Default timeout if no I2C response +#define ISSI_TIMEOUT 100 + +// Reusable buffer for transfers +uint8_t g_twi_transfer_buffer[20]; + +// IS31FL3218 has 18 PWM outputs and a fixed I2C address, so no chaining. +// If used as RGB LED driver, LEDs are assigned RGB,RGB,RGB,RGB,RGB,RGB +uint8_t g_pwm_buffer[18]; +bool g_pwm_buffer_update_required = false; + +void IS31FL3218_write_register(uint8_t reg, uint8_t data) { + g_twi_transfer_buffer[0] = reg; + g_twi_transfer_buffer[1] = data; + i2c_transmit(ISSI_ADDRESS, g_twi_transfer_buffer, 2, ISSI_TIMEOUT); +} + +void IS31FL3218_write_pwm_buffer(uint8_t *pwm_buffer) { + g_twi_transfer_buffer[0] = ISSI_REG_PWM; + for (int i = 0; i < 18; i++) { + g_twi_transfer_buffer[1 + i] = pwm_buffer[i]; + } + + i2c_transmit(ISSI_ADDRESS, g_twi_transfer_buffer, 19, ISSI_TIMEOUT); +} + +void IS31FL3218_init(void) { + // In case we ever want to reinitialize (?) + IS31FL3218_write_register(ISSI_REG_RESET, 0x00); + + // Turn off software shutdown + IS31FL3218_write_register(ISSI_REG_SHUTDOWN, 0x01); + + // Set all PWM values to zero + for (uint8_t i = 0; i < 18; i++) { + IS31FL3218_write_register(ISSI_REG_PWM + i, 0x00); + } + + // Enable all channels + for (uint8_t i = 0; i < 3; i++) { + IS31FL3218_write_register(ISSI_REG_CONTROL + i, 0b00111111); + } + + // Load PWM registers and LED Control register data + IS31FL3218_write_register(ISSI_REG_UPDATE, 0x01); +} + +void IS31FL3218_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { + g_pwm_buffer[index * 3 + 0] = red; + g_pwm_buffer[index * 3 + 1] = green; + g_pwm_buffer[index * 3 + 2] = blue; + g_pwm_buffer_update_required = true; +} + +void IS31FL3218_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { + for (int i = 0; i < 6; i++) { + IS31FL3218_set_color(i, red, green, blue); + } +} + +void IS31FL3218_update_pwm_buffers(void) { + if (g_pwm_buffer_update_required) { + IS31FL3218_write_pwm_buffer(g_pwm_buffer); + // Load PWM registers and LED Control register data + IS31FL3218_write_register(ISSI_REG_UPDATE, 0x01); + } + g_pwm_buffer_update_required = false; +} diff --git a/drivers/led/issi/is31fl3218.h b/drivers/led/issi/is31fl3218.h new file mode 100644 index 0000000000..fa760da191 --- /dev/null +++ b/drivers/led/issi/is31fl3218.h @@ -0,0 +1,25 @@ +/* Copyright 2018 Jason Williams (Wilba) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include +#include + +void IS31FL3218_init(void); +void IS31FL3218_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); +void IS31FL3218_set_color_all(uint8_t red, uint8_t green, uint8_t blue); +void IS31FL3218_update_pwm_buffers(void); diff --git a/drivers/led/issi/is31fl3731-simple.c b/drivers/led/issi/is31fl3731-simple.c new file mode 100644 index 0000000000..d295772f5e --- /dev/null +++ b/drivers/led/issi/is31fl3731-simple.c @@ -0,0 +1,233 @@ +/* Copyright 2017 Jason Williams + * Copyright 2018 Jack Humbert + * Copyright 2019 Clueboard + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "is31fl3731-simple.h" +#include "i2c_master.h" +#include "wait.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) +// The address will vary depending on your wiring: +// 0b1110100 AD <-> GND +// 0b1110111 AD <-> VCC +// 0b1110101 AD <-> SCL +// 0b1110110 AD <-> SDA +#define ISSI_ADDR_DEFAULT 0x74 + +#define ISSI_REG_CONFIG 0x00 +#define ISSI_REG_CONFIG_PICTUREMODE 0x00 +#define ISSI_REG_CONFIG_AUTOPLAYMODE 0x08 +#define ISSI_REG_CONFIG_AUDIOPLAYMODE 0x18 + +#define ISSI_CONF_PICTUREMODE 0x00 +#define ISSI_CONF_AUTOFRAMEMODE 0x04 +#define ISSI_CONF_AUDIOMODE 0x08 + +#define ISSI_REG_PICTUREFRAME 0x01 + +#define ISSI_REG_SHUTDOWN 0x0A +#define ISSI_REG_AUDIOSYNC 0x06 + +#define ISSI_COMMANDREGISTER 0xFD +#define ISSI_BANK_FUNCTIONREG 0x0B // helpfully called 'page nine' + +#ifndef ISSI_TIMEOUT +# define ISSI_TIMEOUT 100 +#endif + +#ifndef ISSI_PERSISTENCE +# define ISSI_PERSISTENCE 0 +#endif + +// Transfer buffer for TWITransmitData() +uint8_t g_twi_transfer_buffer[20]; + +// These buffers match the IS31FL3731 PWM registers 0x24-0xB3. +// Storing them like this is optimal for I2C transfers to the registers. +// We could optimize this and take out the unused registers from these +// buffers and the transfers in IS31FL3731_write_pwm_buffer() but it's +// probably not worth the extra complexity. +uint8_t g_pwm_buffer[LED_DRIVER_COUNT][144]; +bool g_pwm_buffer_update_required[LED_DRIVER_COUNT] = {false}; + +/* There's probably a better way to init this... */ +#if LED_DRIVER_COUNT == 1 +uint8_t g_led_control_registers[LED_DRIVER_COUNT][18] = {{0}}; +#elif LED_DRIVER_COUNT == 2 +uint8_t g_led_control_registers[LED_DRIVER_COUNT][18] = {{0}, {0}}; +#elif LED_DRIVER_COUNT == 3 +uint8_t g_led_control_registers[LED_DRIVER_COUNT][18] = {{0}, {0}, {0}}; +#elif LED_DRIVER_COUNT == 4 +uint8_t g_led_control_registers[LED_DRIVER_COUNT][18] = {{0}, {0}, {0}, {0}}; +#endif +bool g_led_control_registers_update_required[LED_DRIVER_COUNT] = {false}; + +// This is the bit pattern in the LED control registers +// (for matrix A, add one to register for matrix B) +// +// reg - b7 b6 b5 b4 b3 b2 b1 b0 +// 0x00 - R08,R07,R06,R05,R04,R03,R02,R01 +// 0x02 - G08,G07,G06,G05,G04,G03,G02,R00 +// 0x04 - B08,B07,B06,B05,B04,B03,G01,G00 +// 0x06 - - , - , - , - , - ,B02,B01,B00 +// 0x08 - - , - , - , - , - , - , - , - +// 0x0A - B17,B16,B15, - , - , - , - , - +// 0x0C - G17,G16,B14,B13,B12,B11,B10,B09 +// 0x0E - R17,G15,G14,G13,G12,G11,G10,G09 +// 0x10 - R16,R15,R14,R13,R12,R11,R10,R09 + +void IS31FL3731_write_register(uint8_t addr, uint8_t reg, uint8_t data) { + g_twi_transfer_buffer[0] = reg; + g_twi_transfer_buffer[1] = data; + +#if ISSI_PERSISTENCE > 0 + for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) { + if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT) == 0) { + break; + } + } +#else + i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT); +#endif +} + +void IS31FL3731_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer) { + // assumes bank is already selected + + // transmit PWM registers in 9 transfers of 16 bytes + // g_twi_transfer_buffer[] is 20 bytes + + // iterate over the pwm_buffer contents at 16 byte intervals + for (int i = 0; i < 144; i += 16) { + // set the first register, e.g. 0x24, 0x34, 0x44, etc. + g_twi_transfer_buffer[0] = 0x24 + i; + // copy the data from i to i+15 + // device will auto-increment register for data after the first byte + // thus this sets registers 0x24-0x33, 0x34-0x43, etc. in one transfer + for (int j = 0; j < 16; j++) { + g_twi_transfer_buffer[1 + j] = pwm_buffer[i + j]; + } + +#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; + } +#else + i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT); +#endif + } +} + +void IS31FL3731_init(uint8_t addr) { + // In order to avoid the LEDs being driven with garbage data + // in the LED driver's PWM registers, first enable software shutdown, + // then set up the mode and other settings, clear the PWM registers, + // then disable software shutdown. + + // select "function register" bank + IS31FL3731_write_register(addr, ISSI_COMMANDREGISTER, ISSI_BANK_FUNCTIONREG); + + // enable software shutdown + IS31FL3731_write_register(addr, ISSI_REG_SHUTDOWN, 0x00); + + // this delay was copied from other drivers, might not be needed + wait_ms(10); + + // picture mode + IS31FL3731_write_register(addr, ISSI_REG_CONFIG, ISSI_REG_CONFIG_PICTUREMODE); + // display frame 0 + IS31FL3731_write_register(addr, ISSI_REG_PICTUREFRAME, 0x00); + // audio sync off + IS31FL3731_write_register(addr, ISSI_REG_AUDIOSYNC, 0x00); + + // select bank 0 + IS31FL3731_write_register(addr, ISSI_COMMANDREGISTER, 0); + + // turn off all LEDs in the LED control register + for (int i = 0x00; i <= 0x11; i++) { + IS31FL3731_write_register(addr, i, 0x00); + } + + // turn off all LEDs in the blink control register (not really needed) + for (int i = 0x12; i <= 0x23; i++) { + IS31FL3731_write_register(addr, i, 0x00); + } + + // set PWM on all LEDs to 0 + for (int i = 0x24; i <= 0xB3; i++) { + IS31FL3731_write_register(addr, i, 0x00); + } + + // select "function register" bank + IS31FL3731_write_register(addr, ISSI_COMMANDREGISTER, ISSI_BANK_FUNCTIONREG); + + // disable software shutdown + IS31FL3731_write_register(addr, ISSI_REG_SHUTDOWN, 0x01); + + // select bank 0 and leave it selected. + // most usage after initialization is just writing PWM buffers in bank 0 + // as there's not much point in double-buffering + IS31FL3731_write_register(addr, ISSI_COMMANDREGISTER, 0); +} + +void IS31FL3731_set_value(int index, uint8_t value) { + if (index >= 0 && index < DRIVER_LED_TOTAL) { + is31_led led = g_is31_leds[index]; + + // Subtract 0x24 to get the second index of g_pwm_buffer + g_pwm_buffer[led.driver][led.v - 0x24] = value; + g_pwm_buffer_update_required[led.driver] = true; + } +} + +void IS31FL3731_set_value_all(uint8_t value) { + for (int i = 0; i < DRIVER_LED_TOTAL; i++) { + IS31FL3731_set_value(i, value); + } +} + +void IS31FL3731_set_led_control_register(uint8_t index, bool value) { + is31_led led = g_is31_leds[index]; + + uint8_t control_register = (led.v - 0x24) / 8; + uint8_t bit_value = (led.v - 0x24) % 8; + + if (value) { + g_led_control_registers[led.driver][control_register] |= (1 << bit_value); + } else { + g_led_control_registers[led.driver][control_register] &= ~(1 << bit_value); + } + + g_led_control_registers_update_required[led.driver] = true; +} + +void IS31FL3731_update_pwm_buffers(uint8_t addr, uint8_t index) { + if (g_pwm_buffer_update_required[index]) { + IS31FL3731_write_pwm_buffer(addr, g_pwm_buffer[index]); + g_pwm_buffer_update_required[index] = false; + } +} + +void IS31FL3731_update_led_control_registers(uint8_t addr, uint8_t index) { + if (g_led_control_registers_update_required[index]) { + for (int i = 0; i < 18; i++) { + IS31FL3731_write_register(addr, i, g_led_control_registers[index][i]); + } + g_led_control_registers_update_required[index] = false; + } +} diff --git a/drivers/led/issi/is31fl3731-simple.h b/drivers/led/issi/is31fl3731-simple.h new file mode 100644 index 0000000000..9665d6ed35 --- /dev/null +++ b/drivers/led/issi/is31fl3731-simple.h @@ -0,0 +1,207 @@ +/* Copyright 2017 Jason Williams + * Copyright 2018 Jack Humbert + * Copyright 2019 Clueboard + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include +#include + +typedef struct is31_led { + uint8_t driver : 2; + uint8_t v; +} __attribute__((packed)) is31_led; + +extern const is31_led g_is31_leds[DRIVER_LED_TOTAL]; + +void IS31FL3731_init(uint8_t addr); +void IS31FL3731_write_register(uint8_t addr, uint8_t reg, uint8_t data); +void IS31FL3731_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer); + +void IS31FL3731_set_value(int index, uint8_t value); +void IS31FL3731_set_value_all(uint8_t value); + +void IS31FL3731_set_led_control_register(uint8_t index, bool value); + +// This should not be called from an interrupt +// (eg. from a timer interrupt). +// Call this while idle (in between matrix scans). +// If the buffer is dirty, it will update the driver with the buffer. +void IS31FL3731_update_pwm_buffers(uint8_t addr, uint8_t index); +void IS31FL3731_update_led_control_registers(uint8_t addr, uint8_t index); + +#define C1_1 0x24 +#define C1_2 0x25 +#define C1_3 0x26 +#define C1_4 0x27 +#define C1_5 0x28 +#define C1_6 0x29 +#define C1_7 0x2A +#define C1_8 0x2B + +#define C1_9 0x2C +#define C1_10 0x2D +#define C1_11 0x2E +#define C1_12 0x2F +#define C1_13 0x30 +#define C1_14 0x31 +#define C1_15 0x32 +#define C1_16 0x33 + +#define C2_1 0x34 +#define C2_2 0x35 +#define C2_3 0x36 +#define C2_4 0x37 +#define C2_5 0x38 +#define C2_6 0x39 +#define C2_7 0x3A +#define C2_8 0x3B + +#define C2_9 0x3C +#define C2_10 0x3D +#define C2_11 0x3E +#define C2_12 0x3F +#define C2_13 0x40 +#define C2_14 0x41 +#define C2_15 0x42 +#define C2_16 0x43 + +#define C3_1 0x44 +#define C3_2 0x45 +#define C3_3 0x46 +#define C3_4 0x47 +#define C3_5 0x48 +#define C3_6 0x49 +#define C3_7 0x4A +#define C3_8 0x4B + +#define C3_9 0x4C +#define C3_10 0x4D +#define C3_11 0x4E +#define C3_12 0x4F +#define C3_13 0x50 +#define C3_14 0x51 +#define C3_15 0x52 +#define C3_16 0x53 + +#define C4_1 0x54 +#define C4_2 0x55 +#define C4_3 0x56 +#define C4_4 0x57 +#define C4_5 0x58 +#define C4_6 0x59 +#define C4_7 0x5A +#define C4_8 0x5B + +#define C4_9 0x5C +#define C4_10 0x5D +#define C4_11 0x5E +#define C4_12 0x5F +#define C4_13 0x60 +#define C4_14 0x61 +#define C4_15 0x62 +#define C4_16 0x63 + +#define C5_1 0x64 +#define C5_2 0x65 +#define C5_3 0x66 +#define C5_4 0x67 +#define C5_5 0x68 +#define C5_6 0x69 +#define C5_7 0x6A +#define C5_8 0x6B + +#define C5_9 0x6C +#define C5_10 0x6D +#define C5_11 0x6E +#define C5_12 0x6F +#define C5_13 0x70 +#define C5_14 0x71 +#define C5_15 0x72 +#define C5_16 0x73 + +#define C6_1 0x74 +#define C6_2 0x75 +#define C6_3 0x76 +#define C6_4 0x77 +#define C6_5 0x78 +#define C6_6 0x79 +#define C6_7 0x7A +#define C6_8 0x7B + +#define C6_9 0x7C +#define C6_10 0x7D +#define C6_11 0x7E +#define C6_12 0x7F +#define C6_13 0x80 +#define C6_14 0x81 +#define C6_15 0x82 +#define C6_16 0x83 + +#define C7_1 0x84 +#define C7_2 0x85 +#define C7_3 0x86 +#define C7_4 0x87 +#define C7_5 0x88 +#define C7_6 0x89 +#define C7_7 0x8A +#define C7_8 0x8B + +#define C7_9 0x8C +#define C7_10 0x8D +#define C7_11 0x8E +#define C7_12 0x8F +#define C7_13 0x90 +#define C7_14 0x91 +#define C7_15 0x92 +#define C7_16 0x93 + +#define C8_1 0x94 +#define C8_2 0x95 +#define C8_3 0x96 +#define C8_4 0x97 +#define C8_5 0x98 +#define C8_6 0x99 +#define C8_7 0x9A +#define C8_8 0x9B + +#define C8_9 0x9C +#define C8_10 0x9D +#define C8_11 0x9E +#define C8_12 0x9F +#define C8_13 0xA0 +#define C8_14 0xA1 +#define C8_15 0xA2 +#define C8_16 0xA3 + +#define C9_1 0xA4 +#define C9_2 0xA5 +#define C9_3 0xA6 +#define C9_4 0xA7 +#define C9_5 0xA8 +#define C9_6 0xA9 +#define C9_7 0xAA +#define C9_8 0xAB + +#define C9_9 0xAC +#define C9_10 0xAD +#define C9_11 0xAE +#define C9_12 0xAF +#define C9_13 0xB0 +#define C9_14 0xB1 +#define C9_15 0xB2 +#define C9_16 0xB3 diff --git a/drivers/led/issi/is31fl3731.c b/drivers/led/issi/is31fl3731.c new file mode 100644 index 0000000000..110bdc1be4 --- /dev/null +++ b/drivers/led/issi/is31fl3731.c @@ -0,0 +1,237 @@ +/* Copyright 2017 Jason Williams + * Copyright 2018 Jack Humbert + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "is31fl3731.h" +#include "i2c_master.h" +#include "wait.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) +// The address will vary depending on your wiring: +// 0b1110100 AD <-> GND +// 0b1110111 AD <-> VCC +// 0b1110101 AD <-> SCL +// 0b1110110 AD <-> SDA +#define ISSI_ADDR_DEFAULT 0x74 + +#define ISSI_REG_CONFIG 0x00 +#define ISSI_REG_CONFIG_PICTUREMODE 0x00 +#define ISSI_REG_CONFIG_AUTOPLAYMODE 0x08 +#define ISSI_REG_CONFIG_AUDIOPLAYMODE 0x18 + +#define ISSI_CONF_PICTUREMODE 0x00 +#define ISSI_CONF_AUTOFRAMEMODE 0x04 +#define ISSI_CONF_AUDIOMODE 0x08 + +#define ISSI_REG_PICTUREFRAME 0x01 + +#define ISSI_REG_SHUTDOWN 0x0A +#define ISSI_REG_AUDIOSYNC 0x06 + +#define ISSI_COMMANDREGISTER 0xFD +#define ISSI_BANK_FUNCTIONREG 0x0B // helpfully called 'page nine' + +#ifndef ISSI_TIMEOUT +# define ISSI_TIMEOUT 100 +#endif + +#ifndef ISSI_PERSISTENCE +# define ISSI_PERSISTENCE 0 +#endif + +// Transfer buffer for TWITransmitData() +uint8_t g_twi_transfer_buffer[20]; + +// These buffers match the IS31FL3731 PWM registers 0x24-0xB3. +// Storing them like this is optimal for I2C transfers to the registers. +// We could optimize this and take out the unused registers from these +// buffers and the transfers in IS31FL3731_write_pwm_buffer() but it's +// probably not worth the extra complexity. +uint8_t g_pwm_buffer[DRIVER_COUNT][144]; +bool g_pwm_buffer_update_required[DRIVER_COUNT] = {false}; + +uint8_t g_led_control_registers[DRIVER_COUNT][18] = {{0}}; +bool g_led_control_registers_update_required[DRIVER_COUNT] = {false}; + +// This is the bit pattern in the LED control registers +// (for matrix A, add one to register for matrix B) +// +// reg - b7 b6 b5 b4 b3 b2 b1 b0 +// 0x00 - R08,R07,R06,R05,R04,R03,R02,R01 +// 0x02 - G08,G07,G06,G05,G04,G03,G02,R00 +// 0x04 - B08,B07,B06,B05,B04,B03,G01,G00 +// 0x06 - - , - , - , - , - ,B02,B01,B00 +// 0x08 - - , - , - , - , - , - , - , - +// 0x0A - B17,B16,B15, - , - , - , - , - +// 0x0C - G17,G16,B14,B13,B12,B11,B10,B09 +// 0x0E - R17,G15,G14,G13,G12,G11,G10,G09 +// 0x10 - R16,R15,R14,R13,R12,R11,R10,R09 + +void IS31FL3731_write_register(uint8_t addr, uint8_t reg, uint8_t data) { + g_twi_transfer_buffer[0] = reg; + g_twi_transfer_buffer[1] = data; + +#if ISSI_PERSISTENCE > 0 + for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) { + if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT) == 0) break; + } +#else + i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT); +#endif +} + +void IS31FL3731_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer) { + // assumes bank is already selected + + // transmit PWM registers in 9 transfers of 16 bytes + // g_twi_transfer_buffer[] is 20 bytes + + // iterate over the pwm_buffer contents at 16 byte intervals + for (int i = 0; i < 144; i += 16) { + // set the first register, e.g. 0x24, 0x34, 0x44, etc. + g_twi_transfer_buffer[0] = 0x24 + i; + // copy the data from i to i+15 + // device will auto-increment register for data after the first byte + // thus this sets registers 0x24-0x33, 0x34-0x43, etc. in one transfer + for (int j = 0; j < 16; j++) { + g_twi_transfer_buffer[1 + j] = pwm_buffer[i + j]; + } + +#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; + } +#else + i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT); +#endif + } +} + +void IS31FL3731_init(uint8_t addr) { + // In order to avoid the LEDs being driven with garbage data + // in the LED driver's PWM registers, first enable software shutdown, + // then set up the mode and other settings, clear the PWM registers, + // then disable software shutdown. + + // select "function register" bank + IS31FL3731_write_register(addr, ISSI_COMMANDREGISTER, ISSI_BANK_FUNCTIONREG); + + // enable software shutdown + IS31FL3731_write_register(addr, ISSI_REG_SHUTDOWN, 0x00); + + // this delay was copied from other drivers, might not be needed + wait_ms(10); + + // picture mode + IS31FL3731_write_register(addr, ISSI_REG_CONFIG, ISSI_REG_CONFIG_PICTUREMODE); + // display frame 0 + IS31FL3731_write_register(addr, ISSI_REG_PICTUREFRAME, 0x00); + // audio sync off + IS31FL3731_write_register(addr, ISSI_REG_AUDIOSYNC, 0x00); + + // select bank 0 + IS31FL3731_write_register(addr, ISSI_COMMANDREGISTER, 0); + + // turn off all LEDs in the LED control register + for (int i = 0x00; i <= 0x11; i++) { + IS31FL3731_write_register(addr, i, 0x00); + } + + // turn off all LEDs in the blink control register (not really needed) + for (int i = 0x12; i <= 0x23; i++) { + IS31FL3731_write_register(addr, i, 0x00); + } + + // set PWM on all LEDs to 0 + for (int i = 0x24; i <= 0xB3; i++) { + IS31FL3731_write_register(addr, i, 0x00); + } + + // select "function register" bank + IS31FL3731_write_register(addr, ISSI_COMMANDREGISTER, ISSI_BANK_FUNCTIONREG); + + // disable software shutdown + IS31FL3731_write_register(addr, ISSI_REG_SHUTDOWN, 0x01); + + // select bank 0 and leave it selected. + // most usage after initialization is just writing PWM buffers in bank 0 + // as there's not much point in double-buffering + IS31FL3731_write_register(addr, ISSI_COMMANDREGISTER, 0); +} + +void IS31FL3731_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { + if (index >= 0 && index < DRIVER_LED_TOTAL) { + is31_led led = g_is31_leds[index]; + + // Subtract 0x24 to get the second index of g_pwm_buffer + g_pwm_buffer[led.driver][led.r - 0x24] = red; + g_pwm_buffer[led.driver][led.g - 0x24] = green; + g_pwm_buffer[led.driver][led.b - 0x24] = blue; + g_pwm_buffer_update_required[led.driver] = true; + } +} + +void IS31FL3731_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { + for (int i = 0; i < DRIVER_LED_TOTAL; i++) { + IS31FL3731_set_color(i, red, green, blue); + } +} + +void IS31FL3731_set_led_control_register(uint8_t index, bool red, bool green, bool blue) { + is31_led led = g_is31_leds[index]; + + uint8_t control_register_r = (led.r - 0x24) / 8; + uint8_t control_register_g = (led.g - 0x24) / 8; + uint8_t control_register_b = (led.b - 0x24) / 8; + uint8_t bit_r = (led.r - 0x24) % 8; + uint8_t bit_g = (led.g - 0x24) % 8; + uint8_t bit_b = (led.b - 0x24) % 8; + + if (red) { + g_led_control_registers[led.driver][control_register_r] |= (1 << bit_r); + } else { + g_led_control_registers[led.driver][control_register_r] &= ~(1 << bit_r); + } + if (green) { + g_led_control_registers[led.driver][control_register_g] |= (1 << bit_g); + } else { + g_led_control_registers[led.driver][control_register_g] &= ~(1 << bit_g); + } + if (blue) { + g_led_control_registers[led.driver][control_register_b] |= (1 << bit_b); + } else { + g_led_control_registers[led.driver][control_register_b] &= ~(1 << bit_b); + } + + g_led_control_registers_update_required[led.driver] = true; +} + +void IS31FL3731_update_pwm_buffers(uint8_t addr, uint8_t index) { + if (g_pwm_buffer_update_required[index]) { + IS31FL3731_write_pwm_buffer(addr, g_pwm_buffer[index]); + } + g_pwm_buffer_update_required[index] = false; +} + +void IS31FL3731_update_led_control_registers(uint8_t addr, uint8_t index) { + if (g_led_control_registers_update_required[index]) { + for (int i = 0; i < 18; i++) { + IS31FL3731_write_register(addr, i, g_led_control_registers[index][i]); + } + } + g_led_control_registers_update_required[index] = false; +} diff --git a/drivers/led/issi/is31fl3731.h b/drivers/led/issi/is31fl3731.h new file mode 100644 index 0000000000..19e8e6251f --- /dev/null +++ b/drivers/led/issi/is31fl3731.h @@ -0,0 +1,208 @@ +/* Copyright 2017 Jason Williams + * Copyright 2018 Jack Humbert + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include +#include + +typedef struct is31_led { + uint8_t driver : 2; + uint8_t r; + uint8_t g; + uint8_t b; +} __attribute__((packed)) is31_led; + +extern const is31_led g_is31_leds[DRIVER_LED_TOTAL]; + +void IS31FL3731_init(uint8_t addr); +void IS31FL3731_write_register(uint8_t addr, uint8_t reg, uint8_t data); +void IS31FL3731_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer); + +void IS31FL3731_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); +void IS31FL3731_set_color_all(uint8_t red, uint8_t green, uint8_t blue); + +void IS31FL3731_set_led_control_register(uint8_t index, bool red, bool green, bool blue); + +// This should not be called from an interrupt +// (eg. from a timer interrupt). +// Call this while idle (in between matrix scans). +// If the buffer is dirty, it will update the driver with the buffer. +void IS31FL3731_update_pwm_buffers(uint8_t addr, uint8_t index); +void IS31FL3731_update_led_control_registers(uint8_t addr, uint8_t index); + +#define C1_1 0x24 +#define C1_2 0x25 +#define C1_3 0x26 +#define C1_4 0x27 +#define C1_5 0x28 +#define C1_6 0x29 +#define C1_7 0x2A +#define C1_8 0x2B + +#define C1_9 0x2C +#define C1_10 0x2D +#define C1_11 0x2E +#define C1_12 0x2F +#define C1_13 0x30 +#define C1_14 0x31 +#define C1_15 0x32 +#define C1_16 0x33 + +#define C2_1 0x34 +#define C2_2 0x35 +#define C2_3 0x36 +#define C2_4 0x37 +#define C2_5 0x38 +#define C2_6 0x39 +#define C2_7 0x3A +#define C2_8 0x3B + +#define C2_9 0x3C +#define C2_10 0x3D +#define C2_11 0x3E +#define C2_12 0x3F +#define C2_13 0x40 +#define C2_14 0x41 +#define C2_15 0x42 +#define C2_16 0x43 + +#define C3_1 0x44 +#define C3_2 0x45 +#define C3_3 0x46 +#define C3_4 0x47 +#define C3_5 0x48 +#define C3_6 0x49 +#define C3_7 0x4A +#define C3_8 0x4B + +#define C3_9 0x4C +#define C3_10 0x4D +#define C3_11 0x4E +#define C3_12 0x4F +#define C3_13 0x50 +#define C3_14 0x51 +#define C3_15 0x52 +#define C3_16 0x53 + +#define C4_1 0x54 +#define C4_2 0x55 +#define C4_3 0x56 +#define C4_4 0x57 +#define C4_5 0x58 +#define C4_6 0x59 +#define C4_7 0x5A +#define C4_8 0x5B + +#define C4_9 0x5C +#define C4_10 0x5D +#define C4_11 0x5E +#define C4_12 0x5F +#define C4_13 0x60 +#define C4_14 0x61 +#define C4_15 0x62 +#define C4_16 0x63 + +#define C5_1 0x64 +#define C5_2 0x65 +#define C5_3 0x66 +#define C5_4 0x67 +#define C5_5 0x68 +#define C5_6 0x69 +#define C5_7 0x6A +#define C5_8 0x6B + +#define C5_9 0x6C +#define C5_10 0x6D +#define C5_11 0x6E +#define C5_12 0x6F +#define C5_13 0x70 +#define C5_14 0x71 +#define C5_15 0x72 +#define C5_16 0x73 + +#define C6_1 0x74 +#define C6_2 0x75 +#define C6_3 0x76 +#define C6_4 0x77 +#define C6_5 0x78 +#define C6_6 0x79 +#define C6_7 0x7A +#define C6_8 0x7B + +#define C6_9 0x7C +#define C6_10 0x7D +#define C6_11 0x7E +#define C6_12 0x7F +#define C6_13 0x80 +#define C6_14 0x81 +#define C6_15 0x82 +#define C6_16 0x83 + +#define C7_1 0x84 +#define C7_2 0x85 +#define C7_3 0x86 +#define C7_4 0x87 +#define C7_5 0x88 +#define C7_6 0x89 +#define C7_7 0x8A +#define C7_8 0x8B + +#define C7_9 0x8C +#define C7_10 0x8D +#define C7_11 0x8E +#define C7_12 0x8F +#define C7_13 0x90 +#define C7_14 0x91 +#define C7_15 0x92 +#define C7_16 0x93 + +#define C8_1 0x94 +#define C8_2 0x95 +#define C8_3 0x96 +#define C8_4 0x97 +#define C8_5 0x98 +#define C8_6 0x99 +#define C8_7 0x9A +#define C8_8 0x9B + +#define C8_9 0x9C +#define C8_10 0x9D +#define C8_11 0x9E +#define C8_12 0x9F +#define C8_13 0xA0 +#define C8_14 0xA1 +#define C8_15 0xA2 +#define C8_16 0xA3 + +#define C9_1 0xA4 +#define C9_2 0xA5 +#define C9_3 0xA6 +#define C9_4 0xA7 +#define C9_5 0xA8 +#define C9_6 0xA9 +#define C9_7 0xAA +#define C9_8 0xAB + +#define C9_9 0xAC +#define C9_10 0xAD +#define C9_11 0xAE +#define C9_12 0xAF +#define C9_13 0xB0 +#define C9_14 0xB1 +#define C9_15 0xB2 +#define C9_16 0xB3 diff --git a/drivers/led/issi/is31fl3733.c b/drivers/led/issi/is31fl3733.c new file mode 100644 index 0000000000..d99e5339c9 --- /dev/null +++ b/drivers/led/issi/is31fl3733.c @@ -0,0 +1,237 @@ +/* Copyright 2017 Jason Williams + * Copyright 2018 Jack Humbert + * Copyright 2018 Yiancar + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "is31fl3733.h" +#include "i2c_master.h" +#include "wait.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) +// The address will vary depending on your wiring: +// 00 <-> GND +// 01 <-> SCL +// 10 <-> SDA +// 11 <-> VCC +// ADDR1 represents A1:A0 of the 7-bit address. +// ADDR2 represents A3:A2 of the 7-bit address. +// The result is: 0b101(ADDR2)(ADDR1) +#define ISSI_ADDR_DEFAULT 0x50 + +#define ISSI_COMMANDREGISTER 0xFD +#define ISSI_COMMANDREGISTER_WRITELOCK 0xFE +#define ISSI_INTERRUPTMASKREGISTER 0xF0 +#define ISSI_INTERRUPTSTATUSREGISTER 0xF1 + +#define ISSI_PAGE_LEDCONTROL 0x00 // PG0 +#define ISSI_PAGE_PWM 0x01 // PG1 +#define ISSI_PAGE_AUTOBREATH 0x02 // PG2 +#define ISSI_PAGE_FUNCTION 0x03 // PG3 + +#define ISSI_REG_CONFIGURATION 0x00 // PG3 +#define ISSI_REG_GLOBALCURRENT 0x01 // PG3 +#define ISSI_REG_RESET 0x11 // PG3 +#define ISSI_REG_SWPULLUP 0x0F // PG3 +#define ISSI_REG_CSPULLUP 0x10 // PG3 + +#ifndef ISSI_TIMEOUT +# define ISSI_TIMEOUT 100 +#endif + +#ifndef ISSI_PERSISTENCE +# define ISSI_PERSISTENCE 0 +#endif + +// Transfer buffer for TWITransmitData() +uint8_t g_twi_transfer_buffer[20]; + +// These buffers match the IS31FL3733 PWM registers. +// The control buffers match the PG0 LED On/Off registers. +// Storing them like this is optimal for I2C transfers to the registers. +// We could optimize this and take out the unused registers from these +// buffers and the transfers in IS31FL3733_write_pwm_buffer() but it's +// probably not worth the extra complexity. +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}; + +bool IS31FL3733_write_register(uint8_t addr, uint8_t reg, uint8_t data) { + // If the transaction fails function returns false. + g_twi_transfer_buffer[0] = reg; + g_twi_transfer_buffer[1] = data; + +#if ISSI_PERSISTENCE > 0 + for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) { + if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT) != 0) { + return false; + } + } +#else + if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT) != 0) { + return false; + } +#endif + return true; +} + +bool IS31FL3733_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer) { + // Assumes PG1 is already selected. + // If any of the transactions fails function returns false. + // Transmit PWM registers in 12 transfers of 16 bytes. + // g_twi_transfer_buffer[] is 20 bytes + + // Iterate over the pwm_buffer contents at 16 byte intervals. + for (int i = 0; i < 192; i += 16) { + g_twi_transfer_buffer[0] = i; + // Copy the data from i to i+15. + // Device will auto-increment register for data after the first byte + // Thus this sets registers 0x00-0x0F, 0x10-0x1F, etc. in one transfer. + for (int j = 0; j < 16; j++) { + g_twi_transfer_buffer[1 + j] = pwm_buffer[i + j]; + } + +#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; + } + } +#else + if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT) != 0) { + return false; + } +#endif + } + return true; +} + +void IS31FL3733_init(uint8_t addr, uint8_t sync) { + // In order to avoid the LEDs being driven with garbage data + // in the LED driver's PWM registers, shutdown is enabled last. + // Set up the mode and other settings, clear the PWM registers, + // then disable software shutdown. + // Sync is passed so set it according to the datasheet. + + // Unlock the command register. + IS31FL3733_write_register(addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); + + // Select PG0 + IS31FL3733_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_LEDCONTROL); + // Turn off all LEDs. + for (int i = 0x00; i <= 0x17; i++) { + IS31FL3733_write_register(addr, i, 0x00); + } + + // Unlock the command register. + IS31FL3733_write_register(addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); + + // Select PG1 + IS31FL3733_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_PWM); + // Set PWM on all LEDs to 0 + // No need to setup Breath registers to PWM as that is the default. + for (int i = 0x00; i <= 0xBF; i++) { + IS31FL3733_write_register(addr, i, 0x00); + } + + // Unlock the command register. + IS31FL3733_write_register(addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); + + // Select PG3 + IS31FL3733_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_FUNCTION); + // Set global current to maximum. + IS31FL3733_write_register(addr, ISSI_REG_GLOBALCURRENT, 0xFF); + // Disable software shutdown. + IS31FL3733_write_register(addr, ISSI_REG_CONFIGURATION, (sync << 6) | 0x01); + + // Wait 10ms to ensure the device has woken up. + wait_ms(10); +} + +void IS31FL3733_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { + if (index >= 0 && index < DRIVER_LED_TOTAL) { + is31_led led = g_is31_leds[index]; + + 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[led.driver] = true; + } +} + +void IS31FL3733_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { + for (int i = 0; i < DRIVER_LED_TOTAL; i++) { + IS31FL3733_set_color(i, red, green, blue); + } +} + +void IS31FL3733_set_led_control_register(uint8_t index, bool red, bool green, bool blue) { + is31_led led = g_is31_leds[index]; + + uint8_t control_register_r = led.r / 8; + uint8_t control_register_g = led.g / 8; + uint8_t control_register_b = led.b / 8; + uint8_t bit_r = led.r % 8; + uint8_t bit_g = led.g % 8; + uint8_t bit_b = led.b % 8; + + if (red) { + g_led_control_registers[led.driver][control_register_r] |= (1 << bit_r); + } else { + g_led_control_registers[led.driver][control_register_r] &= ~(1 << bit_r); + } + if (green) { + g_led_control_registers[led.driver][control_register_g] |= (1 << bit_g); + } else { + g_led_control_registers[led.driver][control_register_g] &= ~(1 << bit_g); + } + if (blue) { + g_led_control_registers[led.driver][control_register_b] |= (1 << bit_b); + } else { + g_led_control_registers[led.driver][control_register_b] &= ~(1 << bit_b); + } + + g_led_control_registers_update_required[led.driver] = true; +} + +void IS31FL3733_update_pwm_buffers(uint8_t addr, uint8_t index) { + if (g_pwm_buffer_update_required[index]) { + // Firstly we need to unlock the command register and select PG1. + IS31FL3733_write_register(addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); + IS31FL3733_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_PWM); + + // If any of the transactions fail we risk writing dirty PG0, + // refresh page 0 just in case. + if (!IS31FL3733_write_pwm_buffer(addr, g_pwm_buffer[index])) { + g_led_control_registers_update_required[index] = true; + } + } + g_pwm_buffer_update_required[index] = false; +} + +void IS31FL3733_update_led_control_registers(uint8_t addr, uint8_t index) { + if (g_led_control_registers_update_required[index]) { + // Firstly we need to unlock the command register and select PG0 + IS31FL3733_write_register(addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); + IS31FL3733_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_LEDCONTROL); + for (int i = 0; i < 24; i++) { + IS31FL3733_write_register(addr, i, g_led_control_registers[index][i]); + } + } + g_led_control_registers_update_required[index] = false; +} diff --git a/drivers/led/issi/is31fl3733.h b/drivers/led/issi/is31fl3733.h new file mode 100644 index 0000000000..603d505a13 --- /dev/null +++ b/drivers/led/issi/is31fl3733.h @@ -0,0 +1,251 @@ +/* Copyright 2017 Jason Williams + * Copyright 2018 Jack Humbert + * Copyright 2018 Yiancar + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include +#include + +typedef struct is31_led { + uint8_t driver : 2; + uint8_t r; + uint8_t g; + uint8_t b; +} __attribute__((packed)) is31_led; + +extern const is31_led g_is31_leds[DRIVER_LED_TOTAL]; + +void IS31FL3733_init(uint8_t addr, uint8_t sync); +bool IS31FL3733_write_register(uint8_t addr, uint8_t reg, uint8_t data); +bool IS31FL3733_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer); + +void IS31FL3733_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); +void IS31FL3733_set_color_all(uint8_t red, uint8_t green, uint8_t blue); + +void IS31FL3733_set_led_control_register(uint8_t index, bool red, bool green, bool blue); + +// This should not be called from an interrupt +// (eg. from a timer interrupt). +// Call this while idle (in between matrix scans). +// If the buffer is dirty, it will update the driver with the buffer. +void IS31FL3733_update_pwm_buffers(uint8_t addr, uint8_t index); +void IS31FL3733_update_led_control_registers(uint8_t addr, uint8_t index); + +#define A_1 0x00 +#define A_2 0x01 +#define A_3 0x02 +#define A_4 0x03 +#define A_5 0x04 +#define A_6 0x05 +#define A_7 0x06 +#define A_8 0x07 +#define A_9 0x08 +#define A_10 0x09 +#define A_11 0x0A +#define A_12 0x0B +#define A_13 0x0C +#define A_14 0x0D +#define A_15 0x0E +#define A_16 0x0F + +#define B_1 0x10 +#define B_2 0x11 +#define B_3 0x12 +#define B_4 0x13 +#define B_5 0x14 +#define B_6 0x15 +#define B_7 0x16 +#define B_8 0x17 +#define B_9 0x18 +#define B_10 0x19 +#define B_11 0x1A +#define B_12 0x1B +#define B_13 0x1C +#define B_14 0x1D +#define B_15 0x1E +#define B_16 0x1F + +#define C_1 0x20 +#define C_2 0x21 +#define C_3 0x22 +#define C_4 0x23 +#define C_5 0x24 +#define C_6 0x25 +#define C_7 0x26 +#define C_8 0x27 +#define C_9 0x28 +#define C_10 0x29 +#define C_11 0x2A +#define C_12 0x2B +#define C_13 0x2C +#define C_14 0x2D +#define C_15 0x2E +#define C_16 0x2F + +#define D_1 0x30 +#define D_2 0x31 +#define D_3 0x32 +#define D_4 0x33 +#define D_5 0x34 +#define D_6 0x35 +#define D_7 0x36 +#define D_8 0x37 +#define D_9 0x38 +#define D_10 0x39 +#define D_11 0x3A +#define D_12 0x3B +#define D_13 0x3C +#define D_14 0x3D +#define D_15 0x3E +#define D_16 0x3F + +#define E_1 0x40 +#define E_2 0x41 +#define E_3 0x42 +#define E_4 0x43 +#define E_5 0x44 +#define E_6 0x45 +#define E_7 0x46 +#define E_8 0x47 +#define E_9 0x48 +#define E_10 0x49 +#define E_11 0x4A +#define E_12 0x4B +#define E_13 0x4C +#define E_14 0x4D +#define E_15 0x4E +#define E_16 0x4F + +#define F_1 0x50 +#define F_2 0x51 +#define F_3 0x52 +#define F_4 0x53 +#define F_5 0x54 +#define F_6 0x55 +#define F_7 0x56 +#define F_8 0x57 +#define F_9 0x58 +#define F_10 0x59 +#define F_11 0x5A +#define F_12 0x5B +#define F_13 0x5C +#define F_14 0x5D +#define F_15 0x5E +#define F_16 0x5F + +#define G_1 0x60 +#define G_2 0x61 +#define G_3 0x62 +#define G_4 0x63 +#define G_5 0x64 +#define G_6 0x65 +#define G_7 0x66 +#define G_8 0x67 +#define G_9 0x68 +#define G_10 0x69 +#define G_11 0x6A +#define G_12 0x6B +#define G_13 0x6C +#define G_14 0x6D +#define G_15 0x6E +#define G_16 0x6F + +#define H_1 0x70 +#define H_2 0x71 +#define H_3 0x72 +#define H_4 0x73 +#define H_5 0x74 +#define H_6 0x75 +#define H_7 0x76 +#define H_8 0x77 +#define H_9 0x78 +#define H_10 0x79 +#define H_11 0x7A +#define H_12 0x7B +#define H_13 0x7C +#define H_14 0x7D +#define H_15 0x7E +#define H_16 0x7F + +#define I_1 0x80 +#define I_2 0x81 +#define I_3 0x82 +#define I_4 0x83 +#define I_5 0x84 +#define I_6 0x85 +#define I_7 0x86 +#define I_8 0x87 +#define I_9 0x88 +#define I_10 0x89 +#define I_11 0x8A +#define I_12 0x8B +#define I_13 0x8C +#define I_14 0x8D +#define I_15 0x8E +#define I_16 0x8F + +#define J_1 0x90 +#define J_2 0x91 +#define J_3 0x92 +#define J_4 0x93 +#define J_5 0x94 +#define J_6 0x95 +#define J_7 0x96 +#define J_8 0x97 +#define J_9 0x98 +#define J_10 0x99 +#define J_11 0x9A +#define J_12 0x9B +#define J_13 0x9C +#define J_14 0x9D +#define J_15 0x9E +#define J_16 0x9F + +#define K_1 0xA0 +#define K_2 0xA1 +#define K_3 0xA2 +#define K_4 0xA3 +#define K_5 0xA4 +#define K_6 0xA5 +#define K_7 0xA6 +#define K_8 0xA7 +#define K_9 0xA8 +#define K_10 0xA9 +#define K_11 0xAA +#define K_12 0xAB +#define K_13 0xAC +#define K_14 0xAD +#define K_15 0xAE +#define K_16 0xAF + +#define L_1 0xB0 +#define L_2 0xB1 +#define L_3 0xB2 +#define L_4 0xB3 +#define L_5 0xB4 +#define L_6 0xB5 +#define L_7 0xB6 +#define L_8 0xB7 +#define L_9 0xB8 +#define L_10 0xB9 +#define L_11 0xBA +#define L_12 0xBB +#define L_13 0xBC +#define L_14 0xBD +#define L_15 0xBE +#define L_16 0xBF diff --git a/drivers/led/issi/is31fl3736.c b/drivers/led/issi/is31fl3736.c new file mode 100644 index 0000000000..7dece1b1eb --- /dev/null +++ b/drivers/led/issi/is31fl3736.c @@ -0,0 +1,269 @@ +/* Copyright 2018 Jason Williams (Wilba) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "is31fl3736.h" +#include "i2c_master.h" +#include "wait.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) +// The address will vary depending on your wiring: +// 00 <-> GND +// 01 <-> SCL +// 10 <-> SDA +// 11 <-> VCC +// ADDR1 represents A1:A0 of the 7-bit address. +// ADDR2 represents A3:A2 of the 7-bit address. +// The result is: 0b101(ADDR2)(ADDR1) +#define ISSI_ADDR_DEFAULT 0x50 + +#define ISSI_COMMANDREGISTER 0xFD +#define ISSI_COMMANDREGISTER_WRITELOCK 0xFE +#define ISSI_INTERRUPTMASKREGISTER 0xF0 +#define ISSI_INTERRUPTSTATUSREGISTER 0xF1 + +#define ISSI_PAGE_LEDCONTROL 0x00 // PG0 +#define ISSI_PAGE_PWM 0x01 // PG1 +#define ISSI_PAGE_AUTOBREATH 0x02 // PG2 +#define ISSI_PAGE_FUNCTION 0x03 // PG3 + +#define ISSI_REG_CONFIGURATION 0x00 // PG3 +#define ISSI_REG_GLOBALCURRENT 0x01 // PG3 +#define ISSI_REG_RESET 0x11 // PG3 +#define ISSI_REG_SWPULLUP 0x0F // PG3 +#define ISSI_REG_CSPULLUP 0x10 // PG3 + +#ifndef ISSI_TIMEOUT +# define ISSI_TIMEOUT 100 +#endif + +#ifndef ISSI_PERSISTENCE +# define ISSI_PERSISTENCE 0 +#endif + +// Transfer buffer for TWITransmitData() +uint8_t g_twi_transfer_buffer[20]; + +// These buffers match the IS31FL3736 PWM registers. +// The control buffers match the PG0 LED On/Off registers. +// Storing them like this is optimal for I2C transfers to the registers. +// We could optimize this and take out the unused registers from these +// buffers and the transfers in IS31FL3736_write_pwm_buffer() but it's +// 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}, {0}}; +bool g_led_control_registers_update_required = false; + +void IS31FL3736_write_register(uint8_t addr, uint8_t reg, uint8_t data) { + g_twi_transfer_buffer[0] = reg; + g_twi_transfer_buffer[1] = data; + +#if ISSI_PERSISTENCE > 0 + for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) { + if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT) == 0) break; + } +#else + i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT); +#endif +} + +void IS31FL3736_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer) { + // assumes PG1 is already selected + + // transmit PWM registers in 12 transfers of 16 bytes + // g_twi_transfer_buffer[] is 20 bytes + + // iterate over the pwm_buffer contents at 16 byte intervals + for (int i = 0; i < 192; i += 16) { + g_twi_transfer_buffer[0] = i; + // copy the data from i to i+15 + // device will auto-increment register for data after the first byte + // thus this sets registers 0x00-0x0F, 0x10-0x1F, etc. in one transfer + for (int j = 0; j < 16; j++) { + g_twi_transfer_buffer[1 + j] = pwm_buffer[i + j]; + } + +#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; + } +#else + i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT); +#endif + } +} + +void IS31FL3736_init(uint8_t addr) { + // In order to avoid the LEDs being driven with garbage data + // in the LED driver's PWM registers, shutdown is enabled last. + // Set up the mode and other settings, clear the PWM registers, + // then disable software shutdown. + + // Unlock the command register. + IS31FL3736_write_register(addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); + + // Select PG0 + IS31FL3736_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_LEDCONTROL); + // Turn off all LEDs. + for (int i = 0x00; i <= 0x17; i++) { + IS31FL3736_write_register(addr, i, 0x00); + } + + // Unlock the command register. + IS31FL3736_write_register(addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); + + // Select PG1 + IS31FL3736_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_PWM); + // Set PWM on all LEDs to 0 + // No need to setup Breath registers to PWM as that is the default. + for (int i = 0x00; i <= 0xBF; i++) { + IS31FL3736_write_register(addr, i, 0x00); + } + + // Unlock the command register. + IS31FL3736_write_register(addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); + + // Select PG3 + IS31FL3736_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_FUNCTION); + // Set global current to maximum. + IS31FL3736_write_register(addr, ISSI_REG_GLOBALCURRENT, 0xFF); + // Disable software shutdown. + IS31FL3736_write_register(addr, ISSI_REG_CONFIGURATION, 0x01); + + // Wait 10ms to ensure the device has woken up. + wait_ms(10); +} + +void IS31FL3736_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { + if (index >= 0 && index < DRIVER_LED_TOTAL) { + is31_led led = g_is31_leds[index]; + + 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; + } +} + +void IS31FL3736_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { + for (int i = 0; i < DRIVER_LED_TOTAL; i++) { + IS31FL3736_set_color(i, red, green, blue); + } +} + +void IS31FL3736_set_led_control_register(uint8_t index, bool red, bool green, bool blue) { + is31_led led = g_is31_leds[index]; + + // IS31FL3733 + // The PWM register for a matrix position (0x00 to 0xBF) can be + // divided by 8 to get the LED control register (0x00 to 0x17), + // then mod 8 to get the bit position within that register. + + // IS31FL3736 + // The PWM register for a matrix position (0x00 to 0xBF) is interleaved, so: + // A1=0x00 A2=0x02 A3=0x04 A4=0x06 A5=0x08 A6=0x0A A7=0x0C A8=0x0E + // B1=0x10 B2=0x12 B3=0x14 + // But also, the LED control registers (0x00 to 0x17) are also interleaved, so: + // A1-A4=0x00 A5-A8=0x01 + // So, the same math applies. + + uint8_t control_register_r = led.r / 8; + uint8_t control_register_g = led.g / 8; + uint8_t control_register_b = led.b / 8; + + uint8_t bit_r = led.r % 8; + uint8_t bit_g = led.g % 8; + uint8_t bit_b = led.b % 8; + + if (red) { + g_led_control_registers[led.driver][control_register_r] |= (1 << bit_r); + } else { + g_led_control_registers[led.driver][control_register_r] &= ~(1 << bit_r); + } + if (green) { + g_led_control_registers[led.driver][control_register_g] |= (1 << bit_g); + } else { + g_led_control_registers[led.driver][control_register_g] &= ~(1 << bit_g); + } + if (blue) { + g_led_control_registers[led.driver][control_register_b] |= (1 << bit_b); + } else { + g_led_control_registers[led.driver][control_register_b] &= ~(1 << bit_b); + } + + g_led_control_registers_update_required = true; +} + +void IS31FL3736_mono_set_brightness(int index, uint8_t value) { + if (index >= 0 && index < 96) { + // Index in range 0..95 -> A1..A8, B1..B8, etc. + // Map index 0..95 to registers 0x00..0xBE (interleaved) + uint8_t pwm_register = index * 2; + g_pwm_buffer[0][pwm_register] = value; + g_pwm_buffer_update_required = true; + } +} + +void IS31FL3736_mono_set_brightness_all(uint8_t value) { + for (int i = 0; i < 96; i++) { + IS31FL3736_mono_set_brightness(i, value); + } +} + +void IS31FL3736_mono_set_led_control_register(uint8_t index, bool enabled) { + // Index in range 0..95 -> A1..A8, B1..B8, etc. + + // Map index 0..95 to registers 0x00..0xBE (interleaved) + uint8_t pwm_register = index * 2; + // Map register 0x00..0xBE (interleaved) into control register and bit + uint8_t control_register = pwm_register / 8; + uint8_t bit = pwm_register % 8; + + if (enabled) { + g_led_control_registers[0][control_register] |= (1 << bit); + } else { + g_led_control_registers[0][control_register] &= ~(1 << bit); + } + + g_led_control_registers_update_required = true; +} + +void IS31FL3736_update_pwm_buffers(uint8_t addr1, uint8_t addr2) { + if (g_pwm_buffer_update_required) { + // Firstly we need to unlock the command register and select PG1 + IS31FL3736_write_register(addr1, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); + IS31FL3736_write_register(addr1, ISSI_COMMANDREGISTER, ISSI_PAGE_PWM); + + IS31FL3736_write_pwm_buffer(addr1, g_pwm_buffer[0]); + // IS31FL3736_write_pwm_buffer(addr2, g_pwm_buffer[1]); + } + g_pwm_buffer_update_required = false; +} + +void IS31FL3736_update_led_control_registers(uint8_t addr1, uint8_t addr2) { + if (g_led_control_registers_update_required) { + // Firstly we need to unlock the command register and select PG0 + IS31FL3736_write_register(addr1, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); + IS31FL3736_write_register(addr1, ISSI_COMMANDREGISTER, ISSI_PAGE_LEDCONTROL); + for (int i = 0; i < 24; i++) { + IS31FL3736_write_register(addr1, i, g_led_control_registers[0][i]); + // IS31FL3736_write_register(addr2, i, g_led_control_registers[1][i]); + } + g_led_control_registers_update_required = false; + } +} diff --git a/drivers/led/issi/is31fl3736.h b/drivers/led/issi/is31fl3736.h new file mode 100644 index 0000000000..e48e31c279 --- /dev/null +++ b/drivers/led/issi/is31fl3736.h @@ -0,0 +1,168 @@ +/* Copyright 2018 Jason Williams (Wilba) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include +#include + +// Simple interface option. +// If these aren't defined, just define them to make it compile + +#ifndef DRIVER_COUNT +# define DRIVER_COUNT 2 +#endif + +#ifndef DRIVER_LED_TOTAL +# define DRIVER_LED_TOTAL 96 +#endif + +typedef struct is31_led { + uint8_t driver : 2; + uint8_t r; + uint8_t g; + uint8_t b; +} __attribute__((packed)) is31_led; + +extern const is31_led g_is31_leds[DRIVER_LED_TOTAL]; + +void IS31FL3736_init(uint8_t addr); +void IS31FL3736_write_register(uint8_t addr, uint8_t reg, uint8_t data); +void IS31FL3736_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer); + +void IS31FL3736_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); +void IS31FL3736_set_color_all(uint8_t red, uint8_t green, uint8_t blue); + +void IS31FL3736_set_led_control_register(uint8_t index, bool red, bool green, bool blue); + +void IS31FL3736_mono_set_brightness(int index, uint8_t value); +void IS31FL3736_mono_set_brightness_all(uint8_t value); +void IS31FL3736_mono_set_led_control_register(uint8_t index, bool enabled); + +// This should not be called from an interrupt +// (eg. from a timer interrupt). +// Call this while idle (in between matrix scans). +// If the buffer is dirty, it will update the driver with the buffer. +void IS31FL3736_update_pwm_buffers(uint8_t addr1, uint8_t addr2); +void IS31FL3736_update_led_control_registers(uint8_t addr1, uint8_t addr2); + +#define A_1 0x00 +#define A_2 0x02 +#define A_3 0x04 +#define A_4 0x06 +#define A_5 0x08 +#define A_6 0x0A +#define A_7 0x0C +#define A_8 0x0E + +#define B_1 0x10 +#define B_2 0x12 +#define B_3 0x14 +#define B_4 0x16 +#define B_5 0x18 +#define B_6 0x1A +#define B_7 0x1C +#define B_8 0x1E + +#define C_1 0x20 +#define C_2 0x22 +#define C_3 0x24 +#define C_4 0x26 +#define C_5 0x28 +#define C_6 0x2A +#define C_7 0x2C +#define C_8 0x2E + +#define D_1 0x30 +#define D_2 0x32 +#define D_3 0x34 +#define D_4 0x36 +#define D_5 0x38 +#define D_6 0x3A +#define D_7 0x3C +#define D_8 0x3E + +#define E_1 0x40 +#define E_2 0x42 +#define E_3 0x44 +#define E_4 0x46 +#define E_5 0x48 +#define E_6 0x4A +#define E_7 0x4C +#define E_8 0x4E + +#define F_1 0x50 +#define F_2 0x52 +#define F_3 0x54 +#define F_4 0x56 +#define F_5 0x58 +#define F_6 0x5A +#define F_7 0x5C +#define F_8 0x5E + +#define G_1 0x60 +#define G_2 0x62 +#define G_3 0x64 +#define G_4 0x66 +#define G_5 0x68 +#define G_6 0x6A +#define G_7 0x6C +#define G_8 0x6E + +#define H_1 0x70 +#define H_2 0x72 +#define H_3 0x74 +#define H_4 0x76 +#define H_5 0x78 +#define H_6 0x7A +#define H_7 0x7C +#define H_8 0x7E + +#define I_1 0x80 +#define I_2 0x82 +#define I_3 0x84 +#define I_4 0x86 +#define I_5 0x88 +#define I_6 0x8A +#define I_7 0x8C +#define I_8 0x8E + +#define J_1 0x90 +#define J_2 0x92 +#define J_3 0x94 +#define J_4 0x96 +#define J_5 0x98 +#define J_6 0x9A +#define J_7 0x9C +#define J_8 0x9E + +#define K_1 0xA0 +#define K_2 0xA2 +#define K_3 0xA4 +#define K_4 0xA6 +#define K_5 0xA8 +#define K_6 0xAA +#define K_7 0xAC +#define K_8 0xAE + +#define L_1 0xB0 +#define L_2 0xB2 +#define L_3 0xB4 +#define L_4 0xB6 +#define L_5 0xB8 +#define L_6 0xBA +#define L_7 0xBC +#define L_8 0xBE diff --git a/drivers/led/issi/is31fl3737.c b/drivers/led/issi/is31fl3737.c new file mode 100644 index 0000000000..30906b4840 --- /dev/null +++ b/drivers/led/issi/is31fl3737.c @@ -0,0 +1,227 @@ +/* Copyright 2017 Jason Williams + * Copyright 2018 Jack Humbert + * Copyright 2018 Yiancar + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#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) +// The address will vary depending on your wiring: +// 00 <-> GND +// 01 <-> SCL +// 10 <-> SDA +// 11 <-> VCC +// ADDR1 represents A1:A0 of the 7-bit address. +// ADDR2 represents A3:A2 of the 7-bit address. +// The result is: 0b101(ADDR2)(ADDR1) +#define ISSI_ADDR_DEFAULT 0x50 + +#define ISSI_COMMANDREGISTER 0xFD +#define ISSI_COMMANDREGISTER_WRITELOCK 0xFE +#define ISSI_INTERRUPTMASKREGISTER 0xF0 +#define ISSI_INTERRUPTSTATUSREGISTER 0xF1 + +#define ISSI_PAGE_LEDCONTROL 0x00 // PG0 +#define ISSI_PAGE_PWM 0x01 // PG1 +#define ISSI_PAGE_AUTOBREATH 0x02 // PG2 +#define ISSI_PAGE_FUNCTION 0x03 // PG3 + +#define ISSI_REG_CONFIGURATION 0x00 // PG3 +#define ISSI_REG_GLOBALCURRENT 0x01 // PG3 +#define ISSI_REG_RESET 0x11 // PG3 +#define ISSI_REG_SWPULLUP 0x0F // PG3 +#define ISSI_REG_CSPULLUP 0x10 // PG3 + +#ifndef ISSI_TIMEOUT +# define ISSI_TIMEOUT 100 +#endif + +#ifndef ISSI_PERSISTENCE +# define ISSI_PERSISTENCE 0 +#endif + +// Transfer buffer for TWITransmitData() +uint8_t g_twi_transfer_buffer[20]; + +// These buffers match the IS31FL3737 PWM registers. +// The control buffers match the PG0 LED On/Off registers. +// Storing them like this is optimal for I2C transfers to the registers. +// We could optimize this and take out the unused registers from these +// buffers and the transfers in IS31FL3737_write_pwm_buffer() but it's +// probably not worth the extra complexity. + +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; + g_twi_transfer_buffer[1] = data; + +#if ISSI_PERSISTENCE > 0 + for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) { + if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT) == 0) break; + } +#else + i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT); +#endif +} + +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 + // g_twi_transfer_buffer[] is 20 bytes + + // iterate over the pwm_buffer contents at 16 byte intervals + for (int i = 0; i < 192; i += 16) { + g_twi_transfer_buffer[0] = i; + // copy the data from i to i+15 + // device will auto-increment register for data after the first byte + // thus this sets registers 0x00-0x0F, 0x10-0x1F, etc. in one transfer + for (int j = 0; j < 16; j++) { + g_twi_transfer_buffer[1 + j] = pwm_buffer[i + j]; + } + +#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; + } +#else + i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT); +#endif + } +} + +void IS31FL3737_init(uint8_t addr) { + // In order to avoid the LEDs being driven with garbage data + // in the LED driver's PWM registers, shutdown is enabled last. + // Set up the mode and other settings, clear the PWM registers, + // then disable software shutdown. + + // Unlock the command register. + IS31FL3737_write_register(addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); + + // Select PG0 + IS31FL3737_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_LEDCONTROL); + // Turn off all LEDs. + for (int i = 0x00; i <= 0x17; i++) { + IS31FL3737_write_register(addr, i, 0x00); + } + + // Unlock the command register. + IS31FL3737_write_register(addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); + + // Select PG1 + IS31FL3737_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_PWM); + // Set PWM on all LEDs to 0 + // No need to setup Breath registers to PWM as that is the default. + for (int i = 0x00; i <= 0xBF; i++) { + IS31FL3737_write_register(addr, i, 0x00); + } + + // Unlock the command register. + IS31FL3737_write_register(addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); + + // Select PG3 + IS31FL3737_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_FUNCTION); + // Set global current to maximum. + IS31FL3737_write_register(addr, ISSI_REG_GLOBALCURRENT, 0xFF); + // Disable software shutdown. + IS31FL3737_write_register(addr, ISSI_REG_CONFIGURATION, 0x01); + + // Wait 10ms to ensure the device has woken up. + wait_ms(10); +} + +void IS31FL3737_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { + if (index >= 0 && index < DRIVER_LED_TOTAL) { + // copy the led config from progmem to SRAM + is31_led led; + memcpy_P(&led, (&g_is31_leds[index]), sizeof(led)); + + 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[led.driver] = true; + } +} + +void IS31FL3737_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { + for (int i = 0; i < DRIVER_LED_TOTAL; i++) { + IS31FL3737_set_color(i, red, green, blue); + } +} + +void IS31FL3737_set_led_control_register(uint8_t index, bool red, bool green, bool blue) { + // copy the led config from progmem to SRAM + is31_led led; + memcpy_P(&led, (&g_is31_leds[index]), sizeof(led)); + + uint8_t control_register_r = led.r / 8; + uint8_t control_register_g = led.g / 8; + uint8_t control_register_b = led.b / 8; + uint8_t bit_r = led.r % 8; + uint8_t bit_g = led.g % 8; + uint8_t bit_b = led.b % 8; + + if (red) { + g_led_control_registers[led.driver][control_register_r] |= (1 << bit_r); + } else { + g_led_control_registers[led.driver][control_register_r] &= ~(1 << bit_r); + } + if (green) { + g_led_control_registers[led.driver][control_register_g] |= (1 << bit_g); + } else { + g_led_control_registers[led.driver][control_register_g] &= ~(1 << bit_g); + } + if (blue) { + g_led_control_registers[led.driver][control_register_b] |= (1 << bit_b); + } else { + g_led_control_registers[led.driver][control_register_b] &= ~(1 << bit_b); + } + + g_led_control_registers_update_required[led.driver] = true; +} + +void IS31FL3737_update_pwm_buffers(uint8_t addr, uint8_t index) { + if (g_pwm_buffer_update_required[index]) { + // Firstly we need to unlock the command register and select PG1 + IS31FL3737_write_register(addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); + IS31FL3737_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_PWM); + + IS31FL3737_write_pwm_buffer(addr, g_pwm_buffer[index]); + } + g_pwm_buffer_update_required[index] = false; +} + +void IS31FL3737_update_led_control_registers(uint8_t addr, uint8_t index) { + if (g_led_control_registers_update_required[index]) { + // Firstly we need to unlock the command register and select PG0 + IS31FL3737_write_register(addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); + IS31FL3737_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_LEDCONTROL); + for (int i = 0; i < 24; i++) { + IS31FL3737_write_register(addr, i, g_led_control_registers[index][i]); + } + } + g_led_control_registers_update_required[index] = false; +} diff --git a/drivers/led/issi/is31fl3737.h b/drivers/led/issi/is31fl3737.h new file mode 100644 index 0000000000..a1d2281778 --- /dev/null +++ b/drivers/led/issi/is31fl3737.h @@ -0,0 +1,203 @@ +/* Copyright 2017 Jason Williams + * Copyright 2018 Jack Humbert + * Copyright 2018 Yiancar + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include +#include + +typedef struct is31_led { + uint8_t driver : 2; + uint8_t r; + uint8_t g; + uint8_t b; +} __attribute__((packed)) is31_led; + +extern const is31_led g_is31_leds[DRIVER_LED_TOTAL]; + +void IS31FL3737_init(uint8_t addr); +void IS31FL3737_write_register(uint8_t addr, uint8_t reg, uint8_t data); +void IS31FL3737_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer); + +void IS31FL3737_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); +void IS31FL3737_set_color_all(uint8_t red, uint8_t green, uint8_t blue); + +void IS31FL3737_set_led_control_register(uint8_t index, bool red, bool green, bool blue); + +// This should not be called from an interrupt +// (eg. from a timer interrupt). +// Call this while idle (in between matrix scans). +// If the buffer is dirty, it will update the driver with the buffer. +void IS31FL3737_update_pwm_buffers(uint8_t addr1, uint8_t addr2); +void IS31FL3737_update_led_control_registers(uint8_t addr1, uint8_t addr2); + +#define A_1 0x00 +#define A_2 0x01 +#define A_3 0x02 +#define A_4 0x03 +#define A_5 0x04 +#define A_6 0x05 +#define A_7 0x08 +#define A_8 0x09 +#define A_9 0x0A +#define A_10 0x0B +#define A_11 0x0C +#define A_12 0x0D + +#define B_1 0x10 +#define B_2 0x11 +#define B_3 0x12 +#define B_4 0x13 +#define B_5 0x14 +#define B_6 0x15 +#define B_7 0x18 +#define B_8 0x19 +#define B_9 0x1A +#define B_10 0x1B +#define B_11 0x1C +#define B_12 0x1D + +#define C_1 0x20 +#define C_2 0x21 +#define C_3 0x22 +#define C_4 0x23 +#define C_5 0x24 +#define C_6 0x25 +#define C_7 0x28 +#define C_8 0x29 +#define C_9 0x2A +#define C_10 0x2B +#define C_11 0x2C +#define C_12 0x2D + +#define D_1 0x30 +#define D_2 0x31 +#define D_3 0x32 +#define D_4 0x33 +#define D_5 0x34 +#define D_6 0x35 +#define D_7 0x38 +#define D_8 0x39 +#define D_9 0x3A +#define D_10 0x3B +#define D_11 0x3C +#define D_12 0x3D + +#define E_1 0x40 +#define E_2 0x41 +#define E_3 0x42 +#define E_4 0x43 +#define E_5 0x44 +#define E_6 0x45 +#define E_7 0x48 +#define E_8 0x49 +#define E_9 0x4A +#define E_10 0x4B +#define E_11 0x4C +#define E_12 0x4D + +#define F_1 0x50 +#define F_2 0x51 +#define F_3 0x52 +#define F_4 0x53 +#define F_5 0x54 +#define F_6 0x55 +#define F_7 0x58 +#define F_8 0x59 +#define F_9 0x5A +#define F_10 0x5B +#define F_11 0x5C +#define F_12 0x5D + +#define G_1 0x60 +#define G_2 0x61 +#define G_3 0x62 +#define G_4 0x63 +#define G_5 0x64 +#define G_6 0x65 +#define G_7 0x68 +#define G_8 0x69 +#define G_9 0x6A +#define G_10 0x6B +#define G_11 0x6C +#define G_12 0x6D + +#define H_1 0x70 +#define H_2 0x71 +#define H_3 0x72 +#define H_4 0x73 +#define H_5 0x74 +#define H_6 0x75 +#define H_7 0x78 +#define H_8 0x79 +#define H_9 0x7A +#define H_10 0x7B +#define H_11 0x7C +#define H_12 0x7D + +#define I_1 0x80 +#define I_2 0x81 +#define I_3 0x82 +#define I_4 0x83 +#define I_5 0x84 +#define I_6 0x85 +#define I_7 0x88 +#define I_8 0x89 +#define I_9 0x8A +#define I_10 0x8B +#define I_11 0x8C +#define I_12 0x8D + +#define J_1 0x90 +#define J_2 0x91 +#define J_3 0x92 +#define J_4 0x93 +#define J_5 0x94 +#define J_6 0x95 +#define J_7 0x98 +#define J_8 0x99 +#define J_9 0x9A +#define J_10 0x9B +#define J_11 0x9C +#define J_12 0x9D + +#define K_1 0xA0 +#define K_2 0xA1 +#define K_3 0xA2 +#define K_4 0xA3 +#define K_5 0xA4 +#define K_6 0xA5 +#define K_7 0xA8 +#define K_8 0xA9 +#define K_9 0xAA +#define K_10 0xAB +#define K_11 0xAC +#define K_12 0xAD + +#define L_1 0xB0 +#define L_2 0xB1 +#define L_3 0xB2 +#define L_4 0xB3 +#define L_5 0xB4 +#define L_6 0xB5 +#define L_7 0xB8 +#define L_8 0xB9 +#define L_9 0xBA +#define L_10 0xBB +#define L_11 0xBC +#define L_12 0xBD diff --git a/drivers/led/issi/is31fl3741.c b/drivers/led/issi/is31fl3741.c new file mode 100644 index 0000000000..1b533c9b6a --- /dev/null +++ b/drivers/led/issi/is31fl3741.c @@ -0,0 +1,255 @@ +/* Copyright 2017 Jason Williams + * Copyright 2018 Jack Humbert + * Copyright 2018 Yiancar + * Copyright 2020 MelGeek + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "wait.h" + +#include "is31fl3741.h" +#include +#include "i2c_master.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) +// The address will vary depending on your wiring: +// 00 <-> GND +// 01 <-> SCL +// 10 <-> SDA +// 11 <-> VCC +// ADDR1 represents A1:A0 of the 7-bit address. +// ADDR2 represents A3:A2 of the 7-bit address. +// The result is: 0b101(ADDR2)(ADDR1) +#define ISSI_ADDR_DEFAULT 0x60 + +#define ISSI_COMMANDREGISTER 0xFD +#define ISSI_COMMANDREGISTER_WRITELOCK 0xFE +#define ISSI_INTERRUPTMASKREGISTER 0xF0 +#define ISSI_INTERRUPTSTATUSREGISTER 0xF1 +#define ISSI_IDREGISTER 0xFC + +#define ISSI_PAGE_PWM0 0x00 // PG0 +#define ISSI_PAGE_PWM1 0x01 // PG1 +#define ISSI_PAGE_SCALING_0 0x02 // PG2 +#define ISSI_PAGE_SCALING_1 0x03 // PG3 +#define ISSI_PAGE_FUNCTION 0x04 // PG4 + +#define ISSI_REG_CONFIGURATION 0x00 // PG4 +#define ISSI_REG_GLOBALCURRENT 0x01 // PG4 +#define ISSI_REG_PULLDOWNUP 0x02 // PG4 +#define ISSI_REG_RESET 0x3F // PG4 + +#ifndef ISSI_TIMEOUT +# define ISSI_TIMEOUT 100 +#endif + +#ifndef ISSI_PERSISTENCE +# define ISSI_PERSISTENCE 0 +#endif + +#define ISSI_MAX_LEDS 351 + +// Transfer buffer for TWITransmitData() +uint8_t g_twi_transfer_buffer[20] = {0xFF}; + +// These buffers match the IS31FL3741 and IS31FL3741A PWM registers. +// The scaling buffers match the PG2 and PG3 LED On/Off registers. +// Storing them like this is optimal for I2C transfers to the registers. +// We could optimize this and take out the unused registers from these +// buffers and the transfers in IS31FL3741_write_pwm_buffer() but it's +// probably not worth the extra complexity. +uint8_t g_pwm_buffer[DRIVER_COUNT][ISSI_MAX_LEDS]; +bool g_pwm_buffer_update_required = false; +bool g_scaling_registers_update_required[DRIVER_COUNT] = {false}; + +uint8_t g_scaling_registers[DRIVER_COUNT][ISSI_MAX_LEDS]; + +void IS31FL3741_write_register(uint8_t addr, uint8_t reg, uint8_t data) { + g_twi_transfer_buffer[0] = reg; + g_twi_transfer_buffer[1] = data; + +#if ISSI_PERSISTENCE > 0 + for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) { + if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT) == 0) break; + } +#else + i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT); +#endif +} + +bool IS31FL3741_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer) { + // unlock the command register and select PG2 + IS31FL3741_write_register(addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); + IS31FL3741_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_PWM0); + + for (int i = 0; i < 342; i += 18) { + if (i == 180) { + // unlock the command register and select PG2 + IS31FL3741_write_register(addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); + IS31FL3741_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_PWM1); + } + + g_twi_transfer_buffer[0] = i % 180; + memcpy(g_twi_transfer_buffer + 1, pwm_buffer + i, 18); + +#if ISSI_PERSISTENCE > 0 + for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) { + if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 19, ISSI_TIMEOUT) != 0) { + return false; + } + } +#else + if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 19, ISSI_TIMEOUT) != 0) { + return false; + } +#endif + } + + // transfer the left cause the total number is 351 + g_twi_transfer_buffer[0] = 162; + memcpy(g_twi_transfer_buffer + 1, pwm_buffer + 342, 9); + +#if ISSI_PERSISTENCE > 0 + for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) { + if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 10, ISSI_TIMEOUT) != 0) { + return false; + } + } +#else + if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 10, ISSI_TIMEOUT) != 0) { + return false; + } +#endif + + return true; +} + +void IS31FL3741_init(uint8_t addr) { + // In order to avoid the LEDs being driven with garbage data + // in the LED driver's PWM registers, shutdown is enabled last. + // Set up the mode and other settings, clear the PWM registers, + // then disable software shutdown. + // Unlock the command register. + + // Unlock the command register. + IS31FL3741_write_register(addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); + + // Select PG4 + IS31FL3741_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_FUNCTION); + + // Set to Normal operation + IS31FL3741_write_register(addr, ISSI_REG_CONFIGURATION, 0x01); + + // Set Golbal Current Control Register + IS31FL3741_write_register(addr, ISSI_REG_GLOBALCURRENT, 0xFF); + // Set Pull up & Down for SWx CSy + IS31FL3741_write_register(addr, ISSI_REG_PULLDOWNUP, 0x77); + + // IS31FL3741_update_led_scaling_registers(addr, 0xFF, 0xFF, 0xFF); + + // Wait 10ms to ensure the device has woken up. + wait_ms(10); +} + +void IS31FL3741_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { + if (index >= 0 && index < DRIVER_LED_TOTAL) { + is31_led led = g_is31_leds[index]; + + 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; + } +} + +void IS31FL3741_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { + for (int i = 0; i < DRIVER_LED_TOTAL; i++) { + IS31FL3741_set_color(i, red, green, blue); + } +} + +void IS31FL3741_set_led_control_register(uint8_t index, bool red, bool green, bool blue) { + is31_led led = g_is31_leds[index]; + + if (red) { + g_scaling_registers[led.driver][led.r] = 0xFF; + } else { + g_scaling_registers[led.driver][led.r] = 0x00; + } + + if (green) { + g_scaling_registers[led.driver][led.g] = 0xFF; + } else { + g_scaling_registers[led.driver][led.g] = 0x00; + } + + if (blue) { + g_scaling_registers[led.driver][led.b] = 0xFF; + } else { + g_scaling_registers[led.driver][led.b] = 0x00; + } + + g_scaling_registers_update_required[led.driver] = true; +} + +void IS31FL3741_update_pwm_buffers(uint8_t addr1, uint8_t addr2) { + if (g_pwm_buffer_update_required) { + IS31FL3741_write_pwm_buffer(addr1, g_pwm_buffer[0]); + } + + g_pwm_buffer_update_required = false; +} + +void IS31FL3741_set_pwm_buffer(const is31_led *pled, uint8_t red, uint8_t green, uint8_t blue) { + g_pwm_buffer[pled->driver][pled->r] = red; + g_pwm_buffer[pled->driver][pled->g] = green; + g_pwm_buffer[pled->driver][pled->b] = blue; + + g_pwm_buffer_update_required = true; +} + +void IS31FL3741_update_led_control_registers(uint8_t addr, uint8_t index) { + if (g_scaling_registers_update_required[index]) { + // unlock the command register and select PG2 + IS31FL3741_write_register(addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); + IS31FL3741_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_SCALING_0); + + // CS1_SW1 to CS30_SW6 are on PG2 + for (int i = CS1_SW1; i <= CS30_SW6; ++i) { + IS31FL3741_write_register(addr, i, g_scaling_registers[0][i]); + } + + // unlock the command register and select PG3 + IS31FL3741_write_register(addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5); + IS31FL3741_write_register(addr, ISSI_COMMANDREGISTER, ISSI_PAGE_SCALING_1); + + // CS1_SW7 to CS39_SW9 are on PG3 + for (int i = CS1_SW7; i <= CS39_SW9; ++i) { + IS31FL3741_write_register(addr, i - CS1_SW7, g_scaling_registers[0][i]); + } + + g_scaling_registers_update_required[index] = false; + } +} + +void IS31FL3741_set_scaling_registers(const is31_led *pled, uint8_t red, uint8_t green, uint8_t blue) { + g_scaling_registers[pled->driver][pled->r] = red; + g_scaling_registers[pled->driver][pled->g] = green; + g_scaling_registers[pled->driver][pled->b] = blue; + + g_scaling_registers_update_required[pled->driver] = true; +} diff --git a/drivers/led/issi/is31fl3741.h b/drivers/led/issi/is31fl3741.h new file mode 100644 index 0000000000..2df0c5b1a7 --- /dev/null +++ b/drivers/led/issi/is31fl3741.h @@ -0,0 +1,420 @@ +/* Copyright 2017 Jason Williams + * Copyright 2018 Jack Humbert + * Copyright 2018 Yiancar + * Copyright 2020 MelGeek + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include +#include + +typedef struct is31_led { + uint32_t driver : 2; + uint32_t r : 10; + uint32_t g : 10; + uint32_t b : 10; +} __attribute__((packed)) is31_led; + +extern const is31_led g_is31_leds[DRIVER_LED_TOTAL]; + +void IS31FL3741_init(uint8_t addr); +void IS31FL3741_write_register(uint8_t addr, uint8_t reg, uint8_t data); +bool IS31FL3741_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer); + +void IS31FL3741_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); +void IS31FL3741_set_color_all(uint8_t red, uint8_t green, uint8_t blue); + +void IS31FL3741_set_led_control_register(uint8_t index, bool red, bool green, bool blue); + +// This should not be called from an interrupt +// (eg. from a timer interrupt). +// Call this while idle (in between matrix scans). +// If the buffer is dirty, it will update the driver with the buffer. +void IS31FL3741_update_pwm_buffers(uint8_t addr1, uint8_t addr2); +void IS31FL3741_update_led_control_registers(uint8_t addr1, uint8_t addr2); +void IS31FL3741_set_scaling_registers(const is31_led *pled, uint8_t red, uint8_t green, uint8_t blue); + +void IS31FL3741_set_pwm_buffer(const is31_led *pled, uint8_t red, uint8_t green, uint8_t blue); + +#define CS1_SW1 0x00 +#define CS2_SW1 0x01 +#define CS3_SW1 0x02 +#define CS4_SW1 0x03 +#define CS5_SW1 0x04 +#define CS6_SW1 0x05 +#define CS7_SW1 0x06 +#define CS8_SW1 0x07 +#define CS9_SW1 0x08 +#define CS10_SW1 0x09 +#define CS11_SW1 0x0A +#define CS12_SW1 0x0B +#define CS13_SW1 0x0C +#define CS14_SW1 0x0D +#define CS15_SW1 0x0E +#define CS16_SW1 0x0F +#define CS17_SW1 0x10 +#define CS18_SW1 0x11 +#define CS19_SW1 0x12 +#define CS20_SW1 0x13 +#define CS21_SW1 0x14 +#define CS22_SW1 0x15 +#define CS23_SW1 0x16 +#define CS24_SW1 0x17 +#define CS25_SW1 0x18 +#define CS26_SW1 0x19 +#define CS27_SW1 0x1A +#define CS28_SW1 0x1B +#define CS29_SW1 0x1C +#define CS30_SW1 0x1D + +#define CS1_SW2 0x1E +#define CS2_SW2 0x1F +#define CS3_SW2 0x20 +#define CS4_SW2 0x21 +#define CS5_SW2 0x22 +#define CS6_SW2 0x23 +#define CS7_SW2 0x24 +#define CS8_SW2 0x25 +#define CS9_SW2 0x26 +#define CS10_SW2 0x27 +#define CS11_SW2 0x28 +#define CS12_SW2 0x29 +#define CS13_SW2 0x2A +#define CS14_SW2 0x2B +#define CS15_SW2 0x2C +#define CS16_SW2 0x2D +#define CS17_SW2 0x2E +#define CS18_SW2 0x2F +#define CS19_SW2 0x30 +#define CS20_SW2 0x31 +#define CS21_SW2 0x32 +#define CS22_SW2 0x33 +#define CS23_SW2 0x34 +#define CS24_SW2 0x35 +#define CS25_SW2 0x36 +#define CS26_SW2 0x37 +#define CS27_SW2 0x38 +#define CS28_SW2 0x39 +#define CS29_SW2 0x3A +#define CS30_SW2 0x3B + +#define CS1_SW3 0x3C +#define CS2_SW3 0x3D +#define CS3_SW3 0x3E +#define CS4_SW3 0x3F +#define CS5_SW3 0x40 +#define CS6_SW3 0x41 +#define CS7_SW3 0x42 +#define CS8_SW3 0x43 +#define CS9_SW3 0x44 +#define CS10_SW3 0x45 +#define CS11_SW3 0x46 +#define CS12_SW3 0x47 +#define CS13_SW3 0x48 +#define CS14_SW3 0x49 +#define CS15_SW3 0x4A +#define CS16_SW3 0x4B +#define CS17_SW3 0x4C +#define CS18_SW3 0x4D +#define CS19_SW3 0x4E +#define CS20_SW3 0x4F +#define CS21_SW3 0x50 +#define CS22_SW3 0x51 +#define CS23_SW3 0x52 +#define CS24_SW3 0x53 +#define CS25_SW3 0x54 +#define CS26_SW3 0x55 +#define CS27_SW3 0x56 +#define CS28_SW3 0x57 +#define CS29_SW3 0x58 +#define CS30_SW3 0x59 + +#define CS1_SW4 0x5A +#define CS2_SW4 0x5B +#define CS3_SW4 0x5C +#define CS4_SW4 0x5D +#define CS5_SW4 0x5E +#define CS6_SW4 0x5F +#define CS7_SW4 0x60 +#define CS8_SW4 0x61 +#define CS9_SW4 0x62 +#define CS10_SW4 0x63 +#define CS11_SW4 0x64 +#define CS12_SW4 0x65 +#define CS13_SW4 0x66 +#define CS14_SW4 0x67 +#define CS15_SW4 0x68 +#define CS16_SW4 0x69 +#define CS17_SW4 0x6A +#define CS18_SW4 0x6B +#define CS19_SW4 0x6C +#define CS20_SW4 0x6D +#define CS21_SW4 0x6E +#define CS22_SW4 0x6F +#define CS23_SW4 0x70 +#define CS24_SW4 0x71 +#define CS25_SW4 0x72 +#define CS26_SW4 0x73 +#define CS27_SW4 0x74 +#define CS28_SW4 0x75 +#define CS29_SW4 0x76 +#define CS30_SW4 0x77 + +#define CS1_SW5 0x78 +#define CS2_SW5 0x79 +#define CS3_SW5 0x7A +#define CS4_SW5 0x7B +#define CS5_SW5 0x7C +#define CS6_SW5 0x7D +#define CS7_SW5 0x7E +#define CS8_SW5 0x7F +#define CS9_SW5 0x80 +#define CS10_SW5 0x81 +#define CS11_SW5 0x82 +#define CS12_SW5 0x83 +#define CS13_SW5 0x84 +#define CS14_SW5 0x85 +#define CS15_SW5 0x86 +#define CS16_SW5 0x87 +#define CS17_SW5 0x88 +#define CS18_SW5 0x89 +#define CS19_SW5 0x8A +#define CS20_SW5 0x8B +#define CS21_SW5 0x8C +#define CS22_SW5 0x8D +#define CS23_SW5 0x8E +#define CS24_SW5 0x8F +#define CS25_SW5 0x90 +#define CS26_SW5 0x91 +#define CS27_SW5 0x92 +#define CS28_SW5 0x93 +#define CS29_SW5 0x94 +#define CS30_SW5 0x95 + +#define CS1_SW6 0x96 +#define CS2_SW6 0x97 +#define CS3_SW6 0x98 +#define CS4_SW6 0x99 +#define CS5_SW6 0x9A +#define CS6_SW6 0x9B +#define CS7_SW6 0x9C +#define CS8_SW6 0x9D +#define CS9_SW6 0x9E +#define CS10_SW6 0x9F +#define CS11_SW6 0xA0 +#define CS12_SW6 0xA1 +#define CS13_SW6 0xA2 +#define CS14_SW6 0xA3 +#define CS15_SW6 0xA4 +#define CS16_SW6 0xA5 +#define CS17_SW6 0xA6 +#define CS18_SW6 0xA7 +#define CS19_SW6 0xA8 +#define CS20_SW6 0xA9 +#define CS21_SW6 0xAA +#define CS22_SW6 0xAB +#define CS23_SW6 0xAC +#define CS24_SW6 0xAD +#define CS25_SW6 0xAE +#define CS26_SW6 0xAF +#define CS27_SW6 0xB0 +#define CS28_SW6 0xB1 +#define CS29_SW6 0xB2 +#define CS30_SW6 0xB3 + +#define CS1_SW7 0xB4 +#define CS2_SW7 0xB5 +#define CS3_SW7 0xB6 +#define CS4_SW7 0xB7 +#define CS5_SW7 0xB8 +#define CS6_SW7 0xB9 +#define CS7_SW7 0xBA +#define CS8_SW7 0xBB +#define CS9_SW7 0xBC +#define CS10_SW7 0xBD +#define CS11_SW7 0xBE +#define CS12_SW7 0xBF +#define CS13_SW7 0xC0 +#define CS14_SW7 0xC1 +#define CS15_SW7 0xC2 +#define CS16_SW7 0xC3 +#define CS17_SW7 0xC4 +#define CS18_SW7 0xC5 +#define CS19_SW7 0xC6 +#define CS20_SW7 0xC7 +#define CS21_SW7 0xC8 +#define CS22_SW7 0xC9 +#define CS23_SW7 0xCA +#define CS24_SW7 0xCB +#define CS25_SW7 0xCC +#define CS26_SW7 0xCD +#define CS27_SW7 0xCE +#define CS28_SW7 0xCF +#define CS29_SW7 0xD0 +#define CS30_SW7 0xD1 + +#define CS1_SW8 0xD2 +#define CS2_SW8 0xD3 +#define CS3_SW8 0xD4 +#define CS4_SW8 0xD5 +#define CS5_SW8 0xD6 +#define CS6_SW8 0xD7 +#define CS7_SW8 0xD8 +#define CS8_SW8 0xD9 +#define CS9_SW8 0xDA +#define CS10_SW8 0xDB +#define CS11_SW8 0xDC +#define CS12_SW8 0xDD +#define CS13_SW8 0xDE +#define CS14_SW8 0xDF +#define CS15_SW8 0xE0 +#define CS16_SW8 0xE1 +#define CS17_SW8 0xE2 +#define CS18_SW8 0xE3 +#define CS19_SW8 0xE4 +#define CS20_SW8 0xE5 +#define CS21_SW8 0xE6 +#define CS22_SW8 0xE7 +#define CS23_SW8 0xE8 +#define CS24_SW8 0xE9 +#define CS25_SW8 0xEA +#define CS26_SW8 0xEB +#define CS27_SW8 0xEC +#define CS28_SW8 0xED +#define CS29_SW8 0xEE +#define CS30_SW8 0xEF + +#define CS1_SW9 0xF0 +#define CS2_SW9 0xF1 +#define CS3_SW9 0xF2 +#define CS4_SW9 0xF3 +#define CS5_SW9 0xF4 +#define CS6_SW9 0xF5 +#define CS7_SW9 0xF6 +#define CS8_SW9 0xF7 +#define CS9_SW9 0xF8 +#define CS10_SW9 0xF9 +#define CS11_SW9 0xFA +#define CS12_SW9 0xFB +#define CS13_SW9 0xFC +#define CS14_SW9 0xFD +#define CS15_SW9 0xFE +#define CS16_SW9 0xFF +#define CS17_SW9 0x100 +#define CS18_SW9 0x101 +#define CS19_SW9 0x102 +#define CS20_SW9 0x103 +#define CS21_SW9 0x104 +#define CS22_SW9 0x105 +#define CS23_SW9 0x106 +#define CS24_SW9 0x107 +#define CS25_SW9 0x108 +#define CS26_SW9 0x109 +#define CS27_SW9 0x10A +#define CS28_SW9 0x10B +#define CS29_SW9 0x10C +#define CS30_SW9 0x10D + +#define CS31_SW1 0x10E +#define CS32_SW1 0x10F +#define CS33_SW1 0x110 +#define CS34_SW1 0x111 +#define CS35_SW1 0x112 +#define CS36_SW1 0x113 +#define CS37_SW1 0x114 +#define CS38_SW1 0x115 +#define CS39_SW1 0x116 + +#define CS31_SW2 0x117 +#define CS32_SW2 0x118 +#define CS33_SW2 0x119 +#define CS34_SW2 0x11A +#define CS35_SW2 0x11B +#define CS36_SW2 0x11C +#define CS37_SW2 0x11D +#define CS38_SW2 0x11E +#define CS39_SW2 0x11F + +#define CS31_SW3 0x120 +#define CS32_SW3 0x121 +#define CS33_SW3 0x122 +#define CS34_SW3 0x123 +#define CS35_SW3 0x124 +#define CS36_SW3 0x125 +#define CS37_SW3 0x126 +#define CS38_SW3 0x127 +#define CS39_SW3 0x128 + +#define CS31_SW4 0x129 +#define CS32_SW4 0x12A +#define CS33_SW4 0x12B +#define CS34_SW4 0x12C +#define CS35_SW4 0x12D +#define CS36_SW4 0x12E +#define CS37_SW4 0x12F +#define CS38_SW4 0x130 +#define CS39_SW4 0x131 + +#define CS31_SW5 0x132 +#define CS32_SW5 0x133 +#define CS33_SW5 0x134 +#define CS34_SW5 0x135 +#define CS35_SW5 0x136 +#define CS36_SW5 0x137 +#define CS37_SW5 0x138 +#define CS38_SW5 0x139 +#define CS39_SW5 0x13A + +#define CS31_SW6 0x13B +#define CS32_SW6 0x13C +#define CS33_SW6 0x13D +#define CS34_SW6 0x13E +#define CS35_SW6 0x13F +#define CS36_SW6 0x140 +#define CS37_SW6 0x141 +#define CS38_SW6 0x142 +#define CS39_SW6 0x143 + +#define CS31_SW7 0x144 +#define CS32_SW7 0x145 +#define CS33_SW7 0x146 +#define CS34_SW7 0x147 +#define CS35_SW7 0x148 +#define CS36_SW7 0x149 +#define CS37_SW7 0x14A +#define CS38_SW7 0x14B +#define CS39_SW7 0x14C + +#define CS31_SW8 0x14D +#define CS32_SW8 0x14E +#define CS33_SW8 0x14F +#define CS34_SW8 0x150 +#define CS35_SW8 0x151 +#define CS36_SW8 0x152 +#define CS37_SW8 0x153 +#define CS38_SW8 0x154 +#define CS39_SW8 0x155 + +#define CS31_SW9 0x156 +#define CS32_SW9 0x157 +#define CS33_SW9 0x158 +#define CS34_SW9 0x159 +#define CS35_SW9 0x15A +#define CS36_SW9 0x15B +#define CS37_SW9 0x15C +#define CS38_SW9 0x15D +#define CS39_SW9 0x15E diff --git a/keyboards/fallacy/indicators.c b/keyboards/fallacy/indicators.c index 6c80f31678..08c500064d 100755 --- a/keyboards/fallacy/indicators.c +++ b/keyboards/fallacy/indicators.c @@ -15,7 +15,7 @@ */ #include "indicators.h" -#include "drivers/issi/is31fl3731-simple.h" +#include "drivers/led/issi/is31fl3731-simple.h" #include "i2c_master.h" /* Set up IS31FL3731 for use in powering indicator LEDs. Absolutely overkill for this job but it was already in the design. diff --git a/keyboards/fallacy/rules.mk b/keyboards/fallacy/rules.mk index dfc96a31b8..93e02c1695 100755 --- a/keyboards/fallacy/rules.mk +++ b/keyboards/fallacy/rules.mk @@ -24,7 +24,7 @@ AUDIO_ENABLE = no # Audio output # project specific files SRC += indicators.c \ - drivers/issi/is31fl3731-simple.c + drivers/led/issi/is31fl3731-simple.c QUANTUM_LIB_SRC += i2c_master.c LAYOUTS = alice alice_split_bs diff --git a/keyboards/hs60/v2/ansi/rules.mk b/keyboards/hs60/v2/ansi/rules.mk index 1a0c1abbd8..c8030e7040 100644 --- a/keyboards/hs60/v2/ansi/rules.mk +++ b/keyboards/hs60/v2/ansi/rules.mk @@ -31,6 +31,6 @@ LAYOUTS = 60_ansi # project specific files SRC = keyboards/wilba_tech/wt_main.c \ keyboards/wilba_tech/wt_rgb_backlight.c \ - drivers/issi/is31fl3733.c \ + drivers/led/issi/is31fl3733.c \ quantum/color.c \ drivers/chibios/i2c_master.c diff --git a/keyboards/hs60/v2/hhkb/rules.mk b/keyboards/hs60/v2/hhkb/rules.mk index 87d86ccd4c..62c067cb2e 100644 --- a/keyboards/hs60/v2/hhkb/rules.mk +++ b/keyboards/hs60/v2/hhkb/rules.mk @@ -29,6 +29,6 @@ CIE1931_CURVE = yes # project specific files SRC = keyboards/wilba_tech/wt_main.c \ keyboards/wilba_tech/wt_rgb_backlight.c \ - drivers/issi/is31fl3733.c \ + drivers/led/issi/is31fl3733.c \ quantum/color.c \ drivers/chibios/i2c_master.c diff --git a/keyboards/hs60/v2/iso/rules.mk b/keyboards/hs60/v2/iso/rules.mk index 53b801289d..34cfa9e559 100644 --- a/keyboards/hs60/v2/iso/rules.mk +++ b/keyboards/hs60/v2/iso/rules.mk @@ -31,6 +31,6 @@ LAYOUTS = 60_iso # project specific files SRC = keyboards/wilba_tech/wt_main.c \ keyboards/wilba_tech/wt_rgb_backlight.c \ - drivers/issi/is31fl3733.c \ + drivers/led/issi/is31fl3733.c \ quantum/color.c \ drivers/chibios/i2c_master.c diff --git a/keyboards/keebwerk/mega/ansi/ansi.c b/keyboards/keebwerk/mega/ansi/ansi.c index b5eb0bbad2..532cdec9aa 100755 --- a/keyboards/keebwerk/mega/ansi/ansi.c +++ b/keyboards/keebwerk/mega/ansi/ansi.c @@ -18,7 +18,7 @@ #endif #include "ansi.h" -#include "drivers/issi/is31fl3733.h" +#include "drivers/led/issi/is31fl3733.h" uint8_t R = 0; uint8_t G = 0; diff --git a/keyboards/keebwerk/mega/ansi/rules.mk b/keyboards/keebwerk/mega/ansi/rules.mk index 6a1a9cbfad..aaf31579f0 100755 --- a/keyboards/keebwerk/mega/ansi/rules.mk +++ b/keyboards/keebwerk/mega/ansi/rules.mk @@ -34,6 +34,6 @@ LAYOUTS = 65_ansi # project specific files SRC += keyboards/wilba_tech/wt_main.c \ keyboards/wilba_tech/wt_rgb_backlight.c \ - drivers/issi/is31fl3733.c \ + drivers/led/issi/is31fl3733.c \ quantum/color.c QUANTUM_LIB_SRC += drivers/chibios/i2c_master.c diff --git a/keyboards/nebula12/rules.mk b/keyboards/nebula12/rules.mk index 3a423fb78e..ce18e6b2e3 100755 --- a/keyboards/nebula12/rules.mk +++ b/keyboards/nebula12/rules.mk @@ -31,6 +31,6 @@ CIE1931_CURVE = yes # project specific files SRC += keyboards/wilba_tech/wt_main.c \ keyboards/wilba_tech/wt_rgb_backlight.c \ - drivers/issi/is31fl3731.c \ + drivers/led/issi/is31fl3731.c \ quantum/color.c QUANTUM_LIB_SRC += drivers/chibios/i2c_master.c diff --git a/keyboards/nebula68/rules.mk b/keyboards/nebula68/rules.mk index bcf1fd1a8f..14782d6547 100755 --- a/keyboards/nebula68/rules.mk +++ b/keyboards/nebula68/rules.mk @@ -33,6 +33,6 @@ LAYOUTS = 68_ansi # project specific files SRC += keyboards/wilba_tech/wt_main.c \ keyboards/wilba_tech/wt_rgb_backlight.c \ - drivers/issi/is31fl3733.c \ + drivers/led/issi/is31fl3733.c \ quantum/color.c QUANTUM_LIB_SRC += drivers/chibios/i2c_master.c diff --git a/keyboards/nk65/nk65.c b/keyboards/nk65/nk65.c index fae30ac75c..4ed18c114e 100755 --- a/keyboards/nk65/nk65.c +++ b/keyboards/nk65/nk65.c @@ -18,7 +18,7 @@ #endif #include "nk65.h" -#include "drivers/issi/is31fl3733.h" +#include "drivers/led/issi/is31fl3733.h" /* Indicator LEDS are part of the LED driver * Top LED is blue only. LED driver 2 RGB 7 Green channel diff --git a/keyboards/nk65/rules.mk b/keyboards/nk65/rules.mk index e3f02ee09b..bdb8a74903 100755 --- a/keyboards/nk65/rules.mk +++ b/keyboards/nk65/rules.mk @@ -31,6 +31,6 @@ LAYOUTS = 65_ansi # project specific files SRC = keyboards/wilba_tech/wt_main.c \ keyboards/wilba_tech/wt_rgb_backlight.c \ - drivers/issi/is31fl3733.c \ + drivers/led/issi/is31fl3733.c \ quantum/color.c \ drivers/chibios/i2c_master.c diff --git a/keyboards/nk87/nk87.c b/keyboards/nk87/nk87.c index bcebbc651c..c90ba02ea4 100755 --- a/keyboards/nk87/nk87.c +++ b/keyboards/nk87/nk87.c @@ -18,7 +18,7 @@ #endif #include "nk87.h" -#include "drivers/issi/is31fl3733.h" +#include "drivers/led/issi/is31fl3733.h" /* Indicator LEDS are part of the LED driver * Top LED is blue only. LED driver 2 RGB 63 Blue channel diff --git a/keyboards/nk87/rules.mk b/keyboards/nk87/rules.mk index 71f8f3dd80..d7ca223b30 100755 --- a/keyboards/nk87/rules.mk +++ b/keyboards/nk87/rules.mk @@ -32,6 +32,6 @@ CIE1931_CURVE = yes # project specific files SRC = keyboards/wilba_tech/wt_main.c \ keyboards/wilba_tech/wt_rgb_backlight.c \ - drivers/issi/is31fl3733.c \ + drivers/led/issi/is31fl3733.c \ quantum/color.c \ drivers/chibios/i2c_master.c diff --git a/keyboards/tkc/portico/rules.mk b/keyboards/tkc/portico/rules.mk index 84a65370e3..174938417c 100644 --- a/keyboards/tkc/portico/rules.mk +++ b/keyboards/tkc/portico/rules.mk @@ -28,7 +28,7 @@ CIE1931_CURVE = yes SRC += keyboards/wilba_tech/wt_main.c \ keyboards/wilba_tech/wt_rgb_backlight.c \ quantum/color.c \ - drivers/issi/is31fl3731.c + drivers/led/issi/is31fl3731.c QUANTUM_LIB_SRC += i2c_master.c diff --git a/keyboards/wilba_tech/rama_works_kara/rules.mk b/keyboards/wilba_tech/rama_works_kara/rules.mk index 8af9101d35..69efcc01e7 100644 --- a/keyboards/wilba_tech/rama_works_kara/rules.mk +++ b/keyboards/wilba_tech/rama_works_kara/rules.mk @@ -34,5 +34,5 @@ LAYOUTS = 60_hhkb SRC = keyboards/wilba_tech/wt_main.c \ keyboards/wilba_tech/wt_rgb_backlight.c \ quantum/color.c \ - drivers/issi/is31fl3731.c \ + drivers/led/issi/is31fl3731.c \ drivers/avr/i2c_master.c diff --git a/keyboards/wilba_tech/rama_works_koyu/rules.mk b/keyboards/wilba_tech/rama_works_koyu/rules.mk index 809ab26d0e..be95279206 100644 --- a/keyboards/wilba_tech/rama_works_koyu/rules.mk +++ b/keyboards/wilba_tech/rama_works_koyu/rules.mk @@ -42,5 +42,5 @@ CIE1931_CURVE = yes SRC = keyboards/wilba_tech/wt_main.c \ keyboards/wilba_tech/wt_rgb_backlight.c \ quantum/color.c \ - drivers/issi/is31fl3731.c \ + drivers/led/issi/is31fl3731.c \ drivers/avr/i2c_master.c diff --git a/keyboards/wilba_tech/rama_works_m10_c/rules.mk b/keyboards/wilba_tech/rama_works_m10_c/rules.mk index 9f4cc186ed..ab9fdaeb61 100644 --- a/keyboards/wilba_tech/rama_works_m10_c/rules.mk +++ b/keyboards/wilba_tech/rama_works_m10_c/rules.mk @@ -31,5 +31,5 @@ OPT_DEFS += -DNO_SUSPEND_POWER_DOWN SRC = keyboards/wilba_tech/wt_main.c \ keyboards/wilba_tech/wt_rgb_backlight.c \ quantum/color.c \ - drivers/issi/is31fl3731.c \ + drivers/led/issi/is31fl3731.c \ drivers/avr/i2c_master.c diff --git a/keyboards/wilba_tech/rama_works_m50_a/rules.mk b/keyboards/wilba_tech/rama_works_m50_a/rules.mk index 9f4cc186ed..ab9fdaeb61 100644 --- a/keyboards/wilba_tech/rama_works_m50_a/rules.mk +++ b/keyboards/wilba_tech/rama_works_m50_a/rules.mk @@ -31,5 +31,5 @@ OPT_DEFS += -DNO_SUSPEND_POWER_DOWN SRC = keyboards/wilba_tech/wt_main.c \ keyboards/wilba_tech/wt_rgb_backlight.c \ quantum/color.c \ - drivers/issi/is31fl3731.c \ + drivers/led/issi/is31fl3731.c \ drivers/avr/i2c_master.c diff --git a/keyboards/wilba_tech/rama_works_m60_a/rules.mk b/keyboards/wilba_tech/rama_works_m60_a/rules.mk index 7e76a962a2..f44c5856ae 100644 --- a/keyboards/wilba_tech/rama_works_m60_a/rules.mk +++ b/keyboards/wilba_tech/rama_works_m60_a/rules.mk @@ -44,5 +44,5 @@ LAYOUTS = 60_hhkb SRC = keyboards/wilba_tech/wt_main.c \ keyboards/wilba_tech/wt_rgb_backlight.c \ quantum/color.c \ - drivers/issi/is31fl3731.c \ + drivers/led/issi/is31fl3731.c \ drivers/avr/i2c_master.c diff --git a/keyboards/wilba_tech/rama_works_m65_b/rules.mk b/keyboards/wilba_tech/rama_works_m65_b/rules.mk index 9f4cc186ed..ab9fdaeb61 100644 --- a/keyboards/wilba_tech/rama_works_m65_b/rules.mk +++ b/keyboards/wilba_tech/rama_works_m65_b/rules.mk @@ -31,5 +31,5 @@ OPT_DEFS += -DNO_SUSPEND_POWER_DOWN SRC = keyboards/wilba_tech/wt_main.c \ keyboards/wilba_tech/wt_rgb_backlight.c \ quantum/color.c \ - drivers/issi/is31fl3731.c \ + drivers/led/issi/is31fl3731.c \ drivers/avr/i2c_master.c diff --git a/keyboards/wilba_tech/rama_works_m65_bx/rules.mk b/keyboards/wilba_tech/rama_works_m65_bx/rules.mk index 9f4cc186ed..ab9fdaeb61 100644 --- a/keyboards/wilba_tech/rama_works_m65_bx/rules.mk +++ b/keyboards/wilba_tech/rama_works_m65_bx/rules.mk @@ -31,5 +31,5 @@ OPT_DEFS += -DNO_SUSPEND_POWER_DOWN SRC = keyboards/wilba_tech/wt_main.c \ keyboards/wilba_tech/wt_rgb_backlight.c \ quantum/color.c \ - drivers/issi/is31fl3731.c \ + drivers/led/issi/is31fl3731.c \ drivers/avr/i2c_master.c diff --git a/keyboards/wilba_tech/rama_works_m6_b/rules.mk b/keyboards/wilba_tech/rama_works_m6_b/rules.mk index 51d1a0c805..139a968c24 100644 --- a/keyboards/wilba_tech/rama_works_m6_b/rules.mk +++ b/keyboards/wilba_tech/rama_works_m6_b/rules.mk @@ -41,5 +41,5 @@ CIE1931_CURVE = yes SRC = keyboards/wilba_tech/wt_main.c \ keyboards/wilba_tech/wt_rgb_backlight.c \ quantum/color.c \ - drivers/issi/is31fl3218.c \ + drivers/led/issi/is31fl3218.c \ drivers/avr/i2c_master.c diff --git a/keyboards/wilba_tech/rama_works_u80_a/rules.mk b/keyboards/wilba_tech/rama_works_u80_a/rules.mk index 735d2a24ae..654465e683 100644 --- a/keyboards/wilba_tech/rama_works_u80_a/rules.mk +++ b/keyboards/wilba_tech/rama_works_u80_a/rules.mk @@ -34,5 +34,5 @@ CIE1931_CURVE = yes SRC = keyboards/wilba_tech/wt_main.c \ keyboards/wilba_tech/wt_rgb_backlight.c \ quantum/color.c \ - drivers/issi/is31fl3731.c \ + drivers/led/issi/is31fl3731.c \ drivers/avr/i2c_master.c diff --git a/keyboards/wilba_tech/wt60_a/rules.mk b/keyboards/wilba_tech/wt60_a/rules.mk index a0f923a2f3..e892986112 100644 --- a/keyboards/wilba_tech/wt60_a/rules.mk +++ b/keyboards/wilba_tech/wt60_a/rules.mk @@ -30,7 +30,7 @@ BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID AUDIO_ENABLE = no # Audio output on port C6 # project specific files -SRC = drivers/issi/is31fl3736.c \ +SRC = drivers/led/issi/is31fl3736.c \ drivers/avr/i2c_master.c \ quantum/color.c \ keyboards/wilba_tech/wt_mono_backlight.c \ diff --git a/keyboards/wilba_tech/wt60_b/rules.mk b/keyboards/wilba_tech/wt60_b/rules.mk index 50faab968c..e3cbad41ca 100644 --- a/keyboards/wilba_tech/wt60_b/rules.mk +++ b/keyboards/wilba_tech/wt60_b/rules.mk @@ -42,5 +42,5 @@ CIE1931_CURVE = yes SRC = keyboards/wilba_tech/wt_main.c \ keyboards/wilba_tech/wt_rgb_backlight.c \ quantum/color.c \ - drivers/issi/is31fl3731.c \ + drivers/led/issi/is31fl3731.c \ drivers/avr/i2c_master.c diff --git a/keyboards/wilba_tech/wt60_bx/rules.mk b/keyboards/wilba_tech/wt60_bx/rules.mk index 50faab968c..e3cbad41ca 100644 --- a/keyboards/wilba_tech/wt60_bx/rules.mk +++ b/keyboards/wilba_tech/wt60_bx/rules.mk @@ -42,5 +42,5 @@ CIE1931_CURVE = yes SRC = keyboards/wilba_tech/wt_main.c \ keyboards/wilba_tech/wt_rgb_backlight.c \ quantum/color.c \ - drivers/issi/is31fl3731.c \ + drivers/led/issi/is31fl3731.c \ drivers/avr/i2c_master.c diff --git a/keyboards/wilba_tech/wt60_c/rules.mk b/keyboards/wilba_tech/wt60_c/rules.mk index 50faab968c..e3cbad41ca 100644 --- a/keyboards/wilba_tech/wt60_c/rules.mk +++ b/keyboards/wilba_tech/wt60_c/rules.mk @@ -42,5 +42,5 @@ CIE1931_CURVE = yes SRC = keyboards/wilba_tech/wt_main.c \ keyboards/wilba_tech/wt_rgb_backlight.c \ quantum/color.c \ - drivers/issi/is31fl3731.c \ + drivers/led/issi/is31fl3731.c \ drivers/avr/i2c_master.c diff --git a/keyboards/wilba_tech/wt65_a/rules.mk b/keyboards/wilba_tech/wt65_a/rules.mk index a0f923a2f3..e892986112 100644 --- a/keyboards/wilba_tech/wt65_a/rules.mk +++ b/keyboards/wilba_tech/wt65_a/rules.mk @@ -30,7 +30,7 @@ BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID AUDIO_ENABLE = no # Audio output on port C6 # project specific files -SRC = drivers/issi/is31fl3736.c \ +SRC = drivers/led/issi/is31fl3736.c \ drivers/avr/i2c_master.c \ quantum/color.c \ keyboards/wilba_tech/wt_mono_backlight.c \ diff --git a/keyboards/wilba_tech/wt65_b/rules.mk b/keyboards/wilba_tech/wt65_b/rules.mk index a0f923a2f3..e892986112 100644 --- a/keyboards/wilba_tech/wt65_b/rules.mk +++ b/keyboards/wilba_tech/wt65_b/rules.mk @@ -30,7 +30,7 @@ BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID AUDIO_ENABLE = no # Audio output on port C6 # project specific files -SRC = drivers/issi/is31fl3736.c \ +SRC = drivers/led/issi/is31fl3736.c \ drivers/avr/i2c_master.c \ quantum/color.c \ keyboards/wilba_tech/wt_mono_backlight.c \ diff --git a/keyboards/wilba_tech/wt75_a/rules.mk b/keyboards/wilba_tech/wt75_a/rules.mk index a0f923a2f3..e892986112 100644 --- a/keyboards/wilba_tech/wt75_a/rules.mk +++ b/keyboards/wilba_tech/wt75_a/rules.mk @@ -30,7 +30,7 @@ BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID AUDIO_ENABLE = no # Audio output on port C6 # project specific files -SRC = drivers/issi/is31fl3736.c \ +SRC = drivers/led/issi/is31fl3736.c \ drivers/avr/i2c_master.c \ quantum/color.c \ keyboards/wilba_tech/wt_mono_backlight.c \ diff --git a/keyboards/wilba_tech/wt75_b/rules.mk b/keyboards/wilba_tech/wt75_b/rules.mk index a0f923a2f3..e892986112 100644 --- a/keyboards/wilba_tech/wt75_b/rules.mk +++ b/keyboards/wilba_tech/wt75_b/rules.mk @@ -30,7 +30,7 @@ BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID AUDIO_ENABLE = no # Audio output on port C6 # project specific files -SRC = drivers/issi/is31fl3736.c \ +SRC = drivers/led/issi/is31fl3736.c \ drivers/avr/i2c_master.c \ quantum/color.c \ keyboards/wilba_tech/wt_mono_backlight.c \ diff --git a/keyboards/wilba_tech/wt75_c/rules.mk b/keyboards/wilba_tech/wt75_c/rules.mk index a0f923a2f3..e892986112 100644 --- a/keyboards/wilba_tech/wt75_c/rules.mk +++ b/keyboards/wilba_tech/wt75_c/rules.mk @@ -30,7 +30,7 @@ BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID AUDIO_ENABLE = no # Audio output on port C6 # project specific files -SRC = drivers/issi/is31fl3736.c \ +SRC = drivers/led/issi/is31fl3736.c \ drivers/avr/i2c_master.c \ quantum/color.c \ keyboards/wilba_tech/wt_mono_backlight.c \ diff --git a/keyboards/wilba_tech/wt80_a/rules.mk b/keyboards/wilba_tech/wt80_a/rules.mk index a0f923a2f3..e892986112 100644 --- a/keyboards/wilba_tech/wt80_a/rules.mk +++ b/keyboards/wilba_tech/wt80_a/rules.mk @@ -30,7 +30,7 @@ BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID AUDIO_ENABLE = no # Audio output on port C6 # project specific files -SRC = drivers/issi/is31fl3736.c \ +SRC = drivers/led/issi/is31fl3736.c \ drivers/avr/i2c_master.c \ quantum/color.c \ keyboards/wilba_tech/wt_mono_backlight.c \ diff --git a/keyboards/wilba_tech/wt_mono_backlight.c b/keyboards/wilba_tech/wt_mono_backlight.c index fbc3102e8c..310e9afd1b 100644 --- a/keyboards/wilba_tech/wt_mono_backlight.c +++ b/keyboards/wilba_tech/wt_mono_backlight.c @@ -33,7 +33,7 @@ #error VIA_EEPROM_CUSTOM_CONFIG_SIZE was not defined to store backlight_config struct #endif -#include "drivers/issi/is31fl3736.h" +#include "drivers/led/issi/is31fl3736.h" #define ISSI_ADDR_DEFAULT 0x50 diff --git a/keyboards/wilba_tech/wt_rgb_backlight.c b/keyboards/wilba_tech/wt_rgb_backlight.c index e57d061b20..e0359daab4 100644 --- a/keyboards/wilba_tech/wt_rgb_backlight.c +++ b/keyboards/wilba_tech/wt_rgb_backlight.c @@ -78,19 +78,19 @@ LED_TYPE g_ws2812_leds[WS2812_LED_TOTAL]; #endif #if defined(RGB_BACKLIGHT_M6_B) -#include "drivers/issi/is31fl3218.h" +#include "drivers/led/issi/is31fl3218.h" #define BACKLIGHT_LED_COUNT 6 #elif defined(RGB_BACKLIGHT_HS60) -#include "drivers/issi/is31fl3733.h" +#include "drivers/led/issi/is31fl3733.h" #define BACKLIGHT_LED_COUNT 64 #elif defined(RGB_BACKLIGHT_NK65) || defined(RGB_BACKLIGHT_NEBULA68) || defined(RGB_BACKLIGHT_KW_MEGA) -#include "drivers/issi/is31fl3733.h" +#include "drivers/led/issi/is31fl3733.h" #define BACKLIGHT_LED_COUNT 69 #elif defined(RGB_BACKLIGHT_NK87) -#include "drivers/issi/is31fl3733.h" +#include "drivers/led/issi/is31fl3733.h" #define BACKLIGHT_LED_COUNT 128 #else -#include "drivers/issi/is31fl3731.h" +#include "drivers/led/issi/is31fl3731.h" #if defined(RGB_BACKLIGHT_U80_A) #define BACKLIGHT_LED_COUNT 108 #elif defined(RGB_BACKLIGHT_DAWN60) diff --git a/keyboards/wilba_tech/zeal60/rules.mk b/keyboards/wilba_tech/zeal60/rules.mk index 172ebaf6b5..acd1ba36d9 100644 --- a/keyboards/wilba_tech/zeal60/rules.mk +++ b/keyboards/wilba_tech/zeal60/rules.mk @@ -44,5 +44,5 @@ LAYOUTS = 60_ansi 60_iso 60_hhkb 60_ansi_split_bs_rshift SRC = keyboards/wilba_tech/wt_main.c \ keyboards/wilba_tech/wt_rgb_backlight.c \ quantum/color.c \ - drivers/issi/is31fl3731.c \ + drivers/led/issi/is31fl3731.c \ drivers/avr/i2c_master.c diff --git a/keyboards/wilba_tech/zeal65/rules.mk b/keyboards/wilba_tech/zeal65/rules.mk index fcf3d07637..8c3a3772c1 100644 --- a/keyboards/wilba_tech/zeal65/rules.mk +++ b/keyboards/wilba_tech/zeal65/rules.mk @@ -42,5 +42,5 @@ CIE1931_CURVE = yes SRC = keyboards/wilba_tech/wt_main.c \ keyboards/wilba_tech/wt_rgb_backlight.c \ quantum/color.c \ - drivers/issi/is31fl3731.c \ + drivers/led/issi/is31fl3731.c \ drivers/avr/i2c_master.c diff --git a/keyboards/xelus/dawn60/rev1/rules.mk b/keyboards/xelus/dawn60/rev1/rules.mk index 64b6615e81..dda4e5048f 100644 --- a/keyboards/xelus/dawn60/rev1/rules.mk +++ b/keyboards/xelus/dawn60/rev1/rules.mk @@ -42,7 +42,7 @@ CIE1931_CURVE = yes SRC += keyboards/wilba_tech/wt_main.c \ keyboards/wilba_tech/wt_rgb_backlight.c \ quantum/color.c \ - drivers/issi/is31fl3731.c \ + drivers/led/issi/is31fl3731.c \ ws2812.c QUANTUM_LIB_SRC += i2c_master.c diff --git a/keyboards/xelus/dawn60/rev1_qmk/rev1_qmk.c b/keyboards/xelus/dawn60/rev1_qmk/rev1_qmk.c index 901f7a18c2..c305ecae14 100644 --- a/keyboards/xelus/dawn60/rev1_qmk/rev1_qmk.c +++ b/keyboards/xelus/dawn60/rev1_qmk/rev1_qmk.c @@ -18,7 +18,7 @@ #include #include #include -#include "drivers/issi/is31fl3731.h" +#include "drivers/led/issi/is31fl3731.h" #include "ws2812.h" #include "rev1_qmk.h" diff --git a/keyboards/xelus/dawn60/rev1_qmk/rules.mk b/keyboards/xelus/dawn60/rev1_qmk/rules.mk index edfba27304..eb1dd5557c 100644 --- a/keyboards/xelus/dawn60/rev1_qmk/rules.mk +++ b/keyboards/xelus/dawn60/rev1_qmk/rules.mk @@ -42,7 +42,7 @@ RGB_MATRIX_DRIVER = custom # Enable RGB matrix effects. COMMON_VPATH += $(DRIVER_PATH)/issi # project specific files -SRC += drivers/issi/is31fl3731.c \ +SRC += drivers/led/issi/is31fl3731.c \ ws2812.c QUANTUM_LIB_SRC += i2c_master.c diff --git a/keyboards/xelus/pachi/rgb/rgb.c b/keyboards/xelus/pachi/rgb/rgb.c index 1e4ad619c3..ea9812d6b1 100644 --- a/keyboards/xelus/pachi/rgb/rgb.c +++ b/keyboards/xelus/pachi/rgb/rgb.c @@ -23,7 +23,7 @@ void matrix_io_delay(void) { __asm__ volatile("nop\nnop\nnop\n"); } #ifdef RGB_MATRIX_ENABLE #include -#include "drivers/issi/is31fl3741.h" +#include "drivers/led/issi/is31fl3741.h" const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { /* Refer to IS31 manual for these locations * driver diff --git a/keyboards/xelus/pachi/rgb/rules.mk b/keyboards/xelus/pachi/rgb/rules.mk index 6c1b3298c4..bc55888bef 100644 --- a/keyboards/xelus/pachi/rgb/rules.mk +++ b/keyboards/xelus/pachi/rgb/rules.mk @@ -29,7 +29,7 @@ RGB_MATRIX_ENABLE = yes RGB_MATRIX_DRIVER = custom COMMON_VPATH += $(DRIVER_PATH)/issi -SRC += drivers/issi/is31fl3741.c +SRC += drivers/led/issi/is31fl3741.c LTO_ENABLE = yes OPT = 2 -- cgit v1.2.3 From 70fb3e1aaf406cbbd5137916a93ed814d6891ef2 Mon Sep 17 00:00:00 2001 From: Joel Challis Date: Sat, 31 Jul 2021 14:35:30 +0100 Subject: __flash? (#13799) --- docs/feature_led_matrix.md | 2 +- docs/feature_rgb_matrix.md | 8 ++++---- docs/ja/feature_led_matrix.md | 2 +- drivers/led/aw20216.h | 3 ++- drivers/led/issi/is31fl3731-simple.h | 3 ++- drivers/led/issi/is31fl3731.h | 3 ++- drivers/led/issi/is31fl3733.h | 3 ++- drivers/led/issi/is31fl3736.h | 3 ++- drivers/led/issi/is31fl3737.c | 9 ++------- drivers/led/issi/is31fl3737.h | 3 ++- drivers/led/issi/is31fl3741.h | 3 ++- keyboards/clueboard/66_hotswap/gen1/gen1.c | 2 +- keyboards/dp60/dp60.c | 2 +- keyboards/durgod/dgk6x/galaxy/galaxy.c | 2 +- keyboards/durgod/dgk6x/hades/hades.c | 2 +- keyboards/durgod/dgk6x/venus/venus.c | 2 +- keyboards/dztech/dz60rgb/dz60rgb.c | 2 +- keyboards/dztech/dz60rgb_ansi/dz60rgb_ansi.c | 2 +- keyboards/dztech/dz60rgb_wkl/dz60rgb_wkl.c | 2 +- keyboards/dztech/dz65rgb/v1/v1.c | 2 +- keyboards/dztech/dz65rgb/v2/v2.c | 2 +- keyboards/dztech/dz65rgb/v3/v3.c | 2 +- keyboards/ergodox_ez/ergodox_ez.c | 2 +- keyboards/ergodox_infinity/ergodox_infinity.c | 2 +- keyboards/exclusive/e6_rgb/e6_rgb.c | 2 +- keyboards/fallacy/indicators.c | 2 +- keyboards/geekboards/tester/tester.c | 2 +- keyboards/hs60/v1/v1.c | 4 ++-- keyboards/inett_studio/sqx/hotswap/hotswap.c | 2 +- keyboards/inett_studio/sqx/universal/universal.c | 2 +- keyboards/k_type/is31fl3733-dual.h | 2 +- keyboards/k_type/k_type.c | 2 +- keyboards/kbdfans/bella/rgb/rgb.c | 2 +- keyboards/kbdfans/bella/rgb_iso/rgb_iso.c | 2 +- keyboards/kbdfans/kbd67/mkiirgb/mkiirgb.c | 2 +- keyboards/kbdfans/kbdmini/kbdmini.c | 2 +- keyboards/kbdfans/maja/maja.c | 2 +- keyboards/keychron/q1/q1.c | 2 +- keyboards/latin17rgb/latin17rgb.c | 2 +- keyboards/latin60rgb/latin60rgb.c | 2 +- keyboards/latin6rgb/latin6rgb.c | 2 +- keyboards/matrix/m20add/rgb_ring.c | 2 +- keyboards/matrix/noah/noah.c | 2 +- keyboards/mechlovin/adelais/rgb_led/rev2/rev2.c | 2 +- keyboards/mechlovin/delphine/rgb_led/rgb_led.c | 2 +- keyboards/mechlovin/hannah60rgb/rev2/rev2.c | 2 +- keyboards/mechlovin/infinity87/rgb_rev1/rgb_rev1.c | 2 +- keyboards/melgeek/mj61/rev1/rev1.c | 2 +- keyboards/melgeek/mj61/rev2/rev2.c | 2 +- keyboards/melgeek/mj63/rev1/rev1.c | 2 +- keyboards/melgeek/mj63/rev2/rev2.c | 2 +- keyboards/melgeek/mj64/rev1/rev1.c | 2 +- keyboards/melgeek/mj64/rev2/rev2.c | 2 +- keyboards/melgeek/mj64/rev3/rev3.c | 2 +- keyboards/melgeek/mj65/rev3/rev3.c | 2 +- keyboards/melgeek/mojo75/rev1/rev1.c | 2 +- keyboards/melgeek/z70ultra/z70ultra.c | 2 +- keyboards/miller/gm862/gm862.c | 2 +- keyboards/moonlander/moonlander.c | 2 +- keyboards/mt64rgb/mt64rgb.c | 2 +- keyboards/mt84/mt84.c | 2 +- keyboards/opendeck/32/rev1/rev1.c | 2 +- keyboards/planck/ez/ez.c | 2 +- keyboards/planck/light/light.c | 2 +- keyboards/terrazzo/terrazzo.c | 2 +- keyboards/tkc/portico/portico.c | 2 +- keyboards/whitefox/whitefox.c | 2 +- keyboards/wilba_tech/wt_rgb_backlight.c | 16 ++++++++-------- keyboards/xbows/knight/knight.c | 2 +- keyboards/xbows/knight_plus/knight_plus.c | 2 +- keyboards/xbows/nature/nature.c | 2 +- keyboards/xbows/numpad/numpad.c | 2 +- keyboards/xbows/woody/woody.c | 2 +- keyboards/xelus/dawn60/rev1_qmk/rev1_qmk.c | 2 +- keyboards/xelus/pachi/rgb/rgb.c | 2 +- tmk_core/common/progmem.h | 1 + 76 files changed, 95 insertions(+), 92 deletions(-) (limited to 'docs/ja/feature_led_matrix.md') diff --git a/docs/feature_led_matrix.md b/docs/feature_led_matrix.md index afa11e7232..7d7971bbed 100644 --- a/docs/feature_led_matrix.md +++ b/docs/feature_led_matrix.md @@ -52,7 +52,7 @@ Here is an example using 2 drivers. Define these arrays listing all the LEDs in your `.c`: ```c -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { /* Refer to IS31 manual for these locations * driver * | LED address diff --git a/docs/feature_rgb_matrix.md b/docs/feature_rgb_matrix.md index 18e38955ec..670d7e09bf 100644 --- a/docs/feature_rgb_matrix.md +++ b/docs/feature_rgb_matrix.md @@ -52,7 +52,7 @@ Here is an example using 2 drivers. Define these arrays listing all the LEDs in your `.c`: ```c -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { /* Refer to IS31 manual for these locations * driver * | R location @@ -122,7 +122,7 @@ Currently only 4 drivers are supported, but it would be trivial to support all 8 Define these arrays listing all the LEDs in your `.c`: ```c -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { /* Refer to IS31 manual for these locations * driver * | R location @@ -186,7 +186,7 @@ Currently only 2 drivers are supported, but it would be trivial to support all 4 Define these arrays listing all the LEDs in your `.c`: ```c -const is31_led PROGMEM g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { /* Refer to IS31 manual for these locations * driver * | R location @@ -287,7 +287,7 @@ Here is an example using 2 drivers. Define these arrays listing all the LEDs in your `.c`: ```c -const aw_led g_aw_leds[DRIVER_LED_TOTAL] = { +const aw_led __flash g_aw_leds[DRIVER_LED_TOTAL] = { /* Each AW20216 channel is controlled by a register at some offset between 0x00 * and 0xD7 inclusive. * See drivers/awinic/aw20216.h for the mapping between register offsets and diff --git a/docs/ja/feature_led_matrix.md b/docs/ja/feature_led_matrix.md index f132d716f6..6511b28249 100644 --- a/docs/ja/feature_led_matrix.md +++ b/docs/ja/feature_led_matrix.md @@ -52,7 +52,7 @@ I2C IS31FL3731 RGB コントローラを使ったアドレス指定可能な LED `.c` に全ての LED を列挙する配列を定義します: - const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { + const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { /* これらの位置については IS31 マニュアルを参照してください * driver * | LED address diff --git a/drivers/led/aw20216.h b/drivers/led/aw20216.h index c55d9605fc..97ac6dc5bf 100644 --- a/drivers/led/aw20216.h +++ b/drivers/led/aw20216.h @@ -18,6 +18,7 @@ #include #include +#include "progmem.h" #include "gpio.h" typedef struct aw_led { @@ -27,7 +28,7 @@ typedef struct aw_led { uint8_t b; } aw_led; -extern const aw_led g_aw_leds[DRIVER_LED_TOTAL]; +extern const aw_led __flash g_aw_leds[DRIVER_LED_TOTAL]; void AW20216_init(pin_t cs_pin, pin_t en_pin); void AW20216_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); diff --git a/drivers/led/issi/is31fl3731-simple.h b/drivers/led/issi/is31fl3731-simple.h index 9665d6ed35..ecde31eed5 100644 --- a/drivers/led/issi/is31fl3731-simple.h +++ b/drivers/led/issi/is31fl3731-simple.h @@ -20,13 +20,14 @@ #include #include +#include "progmem.h" typedef struct is31_led { uint8_t driver : 2; uint8_t v; } __attribute__((packed)) is31_led; -extern const is31_led g_is31_leds[DRIVER_LED_TOTAL]; +extern const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL]; void IS31FL3731_init(uint8_t addr); void IS31FL3731_write_register(uint8_t addr, uint8_t reg, uint8_t data); diff --git a/drivers/led/issi/is31fl3731.h b/drivers/led/issi/is31fl3731.h index 19e8e6251f..803ea3ea12 100644 --- a/drivers/led/issi/is31fl3731.h +++ b/drivers/led/issi/is31fl3731.h @@ -19,6 +19,7 @@ #include #include +#include "progmem.h" typedef struct is31_led { uint8_t driver : 2; @@ -27,7 +28,7 @@ typedef struct is31_led { uint8_t b; } __attribute__((packed)) is31_led; -extern const is31_led g_is31_leds[DRIVER_LED_TOTAL]; +extern const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL]; void IS31FL3731_init(uint8_t addr); void IS31FL3731_write_register(uint8_t addr, uint8_t reg, uint8_t data); diff --git a/drivers/led/issi/is31fl3733.h b/drivers/led/issi/is31fl3733.h index 603d505a13..64fd38eb19 100644 --- a/drivers/led/issi/is31fl3733.h +++ b/drivers/led/issi/is31fl3733.h @@ -20,6 +20,7 @@ #include #include +#include "progmem.h" typedef struct is31_led { uint8_t driver : 2; @@ -28,7 +29,7 @@ typedef struct is31_led { uint8_t b; } __attribute__((packed)) is31_led; -extern const is31_led g_is31_leds[DRIVER_LED_TOTAL]; +extern const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL]; void IS31FL3733_init(uint8_t addr, uint8_t sync); bool IS31FL3733_write_register(uint8_t addr, uint8_t reg, uint8_t data); diff --git a/drivers/led/issi/is31fl3736.h b/drivers/led/issi/is31fl3736.h index e48e31c279..c956c87f7c 100644 --- a/drivers/led/issi/is31fl3736.h +++ b/drivers/led/issi/is31fl3736.h @@ -18,6 +18,7 @@ #include #include +#include "progmem.h" // Simple interface option. // If these aren't defined, just define them to make it compile @@ -37,7 +38,7 @@ typedef struct is31_led { uint8_t b; } __attribute__((packed)) is31_led; -extern const is31_led g_is31_leds[DRIVER_LED_TOTAL]; +extern const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL]; void IS31FL3736_init(uint8_t addr); void IS31FL3736_write_register(uint8_t addr, uint8_t reg, uint8_t data); diff --git a/drivers/led/issi/is31fl3737.c b/drivers/led/issi/is31fl3737.c index 30906b4840..0bb4ddd425 100644 --- a/drivers/led/issi/is31fl3737.c +++ b/drivers/led/issi/is31fl3737.c @@ -19,7 +19,6 @@ #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) @@ -155,9 +154,7 @@ void IS31FL3737_init(uint8_t addr) { void IS31FL3737_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { if (index >= 0 && index < DRIVER_LED_TOTAL) { - // copy the led config from progmem to SRAM - is31_led led; - memcpy_P(&led, (&g_is31_leds[index]), sizeof(led)); + is31_led led = g_is31_leds[index]; g_pwm_buffer[led.driver][led.r] = red; g_pwm_buffer[led.driver][led.g] = green; @@ -173,9 +170,7 @@ void IS31FL3737_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { } void IS31FL3737_set_led_control_register(uint8_t index, bool red, bool green, bool blue) { - // copy the led config from progmem to SRAM - is31_led led; - memcpy_P(&led, (&g_is31_leds[index]), sizeof(led)); + is31_led led = g_is31_leds[index]; uint8_t control_register_r = led.r / 8; uint8_t control_register_g = led.g / 8; diff --git a/drivers/led/issi/is31fl3737.h b/drivers/led/issi/is31fl3737.h index a1d2281778..06886e9c9b 100644 --- a/drivers/led/issi/is31fl3737.h +++ b/drivers/led/issi/is31fl3737.h @@ -20,6 +20,7 @@ #include #include +#include "progmem.h" typedef struct is31_led { uint8_t driver : 2; @@ -28,7 +29,7 @@ typedef struct is31_led { uint8_t b; } __attribute__((packed)) is31_led; -extern const is31_led g_is31_leds[DRIVER_LED_TOTAL]; +extern const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL]; void IS31FL3737_init(uint8_t addr); void IS31FL3737_write_register(uint8_t addr, uint8_t reg, uint8_t data); diff --git a/drivers/led/issi/is31fl3741.h b/drivers/led/issi/is31fl3741.h index 2df0c5b1a7..cea6761ca8 100644 --- a/drivers/led/issi/is31fl3741.h +++ b/drivers/led/issi/is31fl3741.h @@ -21,6 +21,7 @@ #include #include +#include "progmem.h" typedef struct is31_led { uint32_t driver : 2; @@ -29,7 +30,7 @@ typedef struct is31_led { uint32_t b : 10; } __attribute__((packed)) is31_led; -extern const is31_led g_is31_leds[DRIVER_LED_TOTAL]; +extern const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL]; void IS31FL3741_init(uint8_t addr); void IS31FL3741_write_register(uint8_t addr, uint8_t reg, uint8_t data); diff --git a/keyboards/clueboard/66_hotswap/gen1/gen1.c b/keyboards/clueboard/66_hotswap/gen1/gen1.c index 339bd78d5a..8e3db70d07 100644 --- a/keyboards/clueboard/66_hotswap/gen1/gen1.c +++ b/keyboards/clueboard/66_hotswap/gen1/gen1.c @@ -16,7 +16,7 @@ #include "gen1.h" #ifdef LED_MATRIX_ENABLE -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { /* Refer to IS31 manual for these locations * driver * | LED address diff --git a/keyboards/dp60/dp60.c b/keyboards/dp60/dp60.c index 475084b049..87543b2a1c 100644 --- a/keyboards/dp60/dp60.c +++ b/keyboards/dp60/dp60.c @@ -17,7 +17,7 @@ #include "dp60.h" #ifdef RGB_MATRIX_ENABLE -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { /* Refer to IS31 manual for these locations * driver * | R location diff --git a/keyboards/durgod/dgk6x/galaxy/galaxy.c b/keyboards/durgod/dgk6x/galaxy/galaxy.c index d101533b16..5f793ed85b 100644 --- a/keyboards/durgod/dgk6x/galaxy/galaxy.c +++ b/keyboards/durgod/dgk6x/galaxy/galaxy.c @@ -18,7 +18,7 @@ #ifdef RGB_MATRIX_ENABLE -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { /* Refer to IS31 manual for these locations * driver * | R location diff --git a/keyboards/durgod/dgk6x/hades/hades.c b/keyboards/durgod/dgk6x/hades/hades.c index 21b2722913..3e235683f1 100644 --- a/keyboards/durgod/dgk6x/hades/hades.c +++ b/keyboards/durgod/dgk6x/hades/hades.c @@ -19,7 +19,7 @@ #ifdef RGB_MATRIX_ENABLE -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { /* Refer to IS31 manual for these locations * driver * | R location diff --git a/keyboards/durgod/dgk6x/venus/venus.c b/keyboards/durgod/dgk6x/venus/venus.c index 2d49b34daf..3398acb19d 100644 --- a/keyboards/durgod/dgk6x/venus/venus.c +++ b/keyboards/durgod/dgk6x/venus/venus.c @@ -18,7 +18,7 @@ #ifdef RGB_MATRIX_ENABLE -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { /* Refer to IS31 manual for these locations * driver * | R location diff --git a/keyboards/dztech/dz60rgb/dz60rgb.c b/keyboards/dztech/dz60rgb/dz60rgb.c index aa02fb902d..a7fc3dbc5c 100644 --- a/keyboards/dztech/dz60rgb/dz60rgb.c +++ b/keyboards/dztech/dz60rgb/dz60rgb.c @@ -1,7 +1,7 @@ #include "dz60rgb.h" #ifdef RGB_MATRIX_ENABLE -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { { 0, K_14, J_14, L_14 }, { 0, K_13, J_13, L_13 }, { 0, K_12, J_12, L_12 }, diff --git a/keyboards/dztech/dz60rgb_ansi/dz60rgb_ansi.c b/keyboards/dztech/dz60rgb_ansi/dz60rgb_ansi.c index 4bb5938b66..ab24410912 100644 --- a/keyboards/dztech/dz60rgb_ansi/dz60rgb_ansi.c +++ b/keyboards/dztech/dz60rgb_ansi/dz60rgb_ansi.c @@ -1,7 +1,7 @@ #include "dz60rgb_ansi.h" #ifdef RGB_MATRIX_ENABLE -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { { 0, K_14, J_14, L_14 }, { 0, K_13, J_13, L_13 }, { 0, K_12, J_12, L_12 }, diff --git a/keyboards/dztech/dz60rgb_wkl/dz60rgb_wkl.c b/keyboards/dztech/dz60rgb_wkl/dz60rgb_wkl.c index b57560bacd..455624471d 100644 --- a/keyboards/dztech/dz60rgb_wkl/dz60rgb_wkl.c +++ b/keyboards/dztech/dz60rgb_wkl/dz60rgb_wkl.c @@ -1,7 +1,7 @@ #include "dz60rgb_wkl.h" #ifdef RGB_MATRIX_ENABLE -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { { 0, H_15, G_15, I_15 }, { 0, K_14, J_14, L_14 }, { 0, K_13, J_13, L_13 }, diff --git a/keyboards/dztech/dz65rgb/v1/v1.c b/keyboards/dztech/dz65rgb/v1/v1.c index 8a3f0e27bf..aabe41c313 100644 --- a/keyboards/dztech/dz65rgb/v1/v1.c +++ b/keyboards/dztech/dz65rgb/v1/v1.c @@ -16,7 +16,7 @@ #include "v1.h" #ifdef RGB_MATRIX_ENABLE -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { { 0, C8_8, C7_8, C6_8 }, { 0, C9_8, C7_7, C6_7 }, { 0, C9_7, C8_7, C6_6 }, diff --git a/keyboards/dztech/dz65rgb/v2/v2.c b/keyboards/dztech/dz65rgb/v2/v2.c index 788709d989..dce167c73f 100644 --- a/keyboards/dztech/dz65rgb/v2/v2.c +++ b/keyboards/dztech/dz65rgb/v2/v2.c @@ -16,7 +16,7 @@ #include "v2.h" #ifdef RGB_MATRIX_ENABLE -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { { 0, C8_8, C7_8, C6_8 }, { 0, C9_8, C7_7, C6_7 }, { 0, C9_7, C8_7, C6_6 }, diff --git a/keyboards/dztech/dz65rgb/v3/v3.c b/keyboards/dztech/dz65rgb/v3/v3.c index dec75814ca..c3719bfa51 100755 --- a/keyboards/dztech/dz65rgb/v3/v3.c +++ b/keyboards/dztech/dz65rgb/v3/v3.c @@ -18,7 +18,7 @@ #ifdef RGB_MATRIX_ENABLE -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { {0, CS21_SW1, CS20_SW1, CS19_SW1}, {0, CS21_SW2, CS20_SW2, CS19_SW2}, {0, CS21_SW3, CS20_SW3, CS19_SW3}, diff --git a/keyboards/ergodox_ez/ergodox_ez.c b/keyboards/ergodox_ez/ergodox_ez.c index 47dd1b0cc9..7af76cb624 100644 --- a/keyboards/ergodox_ez/ergodox_ez.c +++ b/keyboards/ergodox_ez/ergodox_ez.c @@ -243,7 +243,7 @@ const keypos_t PROGMEM hand_swap_config[MATRIX_ROWS][MATRIX_COLS] = { #ifdef RGB_MATRIX_ENABLE // clang-format off -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { /* driver * | R location * | | G location diff --git a/keyboards/ergodox_infinity/ergodox_infinity.c b/keyboards/ergodox_infinity/ergodox_infinity.c index 76cbca07f8..90aa522427 100644 --- a/keyboards/ergodox_infinity/ergodox_infinity.c +++ b/keyboards/ergodox_infinity/ergodox_infinity.c @@ -191,7 +191,7 @@ const keypos_t PROGMEM hand_swap_config[MATRIX_ROWS][MATRIX_COLS] = { #endif #ifdef LED_MATRIX_ENABLE -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { // The numbers in the comments are the led numbers DXX on the PCB /* Refer to IS31 manual for these locations * driver diff --git a/keyboards/exclusive/e6_rgb/e6_rgb.c b/keyboards/exclusive/e6_rgb/e6_rgb.c index 0e248a2023..e0d313f835 100644 --- a/keyboards/exclusive/e6_rgb/e6_rgb.c +++ b/keyboards/exclusive/e6_rgb/e6_rgb.c @@ -11,7 +11,7 @@ void matrix_init_kb(void) { matrix_init_user(); } -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { /* Refer to IS31 manual for these locations * driver * | R location diff --git a/keyboards/fallacy/indicators.c b/keyboards/fallacy/indicators.c index 08c500064d..dcf1b4de07 100755 --- a/keyboards/fallacy/indicators.c +++ b/keyboards/fallacy/indicators.c @@ -54,7 +54,7 @@ void set_fallacy_led(int index, bool state) { /* define LED matrix */ -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { {0, C1_1}, {0, C2_1}, {0, C3_1}, diff --git a/keyboards/geekboards/tester/tester.c b/keyboards/geekboards/tester/tester.c index 4fab1a7012..0c5c056cc0 100644 --- a/keyboards/geekboards/tester/tester.c +++ b/keyboards/geekboards/tester/tester.c @@ -1,5 +1,5 @@ #include "tester.h" -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { /* Refer to IS31 manual for these locations * driver * | R location diff --git a/keyboards/hs60/v1/v1.c b/keyboards/hs60/v1/v1.c index 70c1c2128e..58b19b6408 100644 --- a/keyboards/hs60/v1/v1.c +++ b/keyboards/hs60/v1/v1.c @@ -91,7 +91,7 @@ void raw_hid_receive( uint8_t *data, uint8_t length ) #ifdef HS60_ANSI -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { /* Refer to IS31 manual for these locations * driver * | R location @@ -199,7 +199,7 @@ led_config_t g_led_config = { { #else -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { /* Refer to IS31 manual for these locations * driver * | R location diff --git a/keyboards/inett_studio/sqx/hotswap/hotswap.c b/keyboards/inett_studio/sqx/hotswap/hotswap.c index be8985c87e..5b3c8df822 100644 --- a/keyboards/inett_studio/sqx/hotswap/hotswap.c +++ b/keyboards/inett_studio/sqx/hotswap/hotswap.c @@ -20,7 +20,7 @@ #include "hotswap.h" #ifdef RGB_MATRIX_ENABLE -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { /* Refer to IS31 manual for these locations * driver * | R location diff --git a/keyboards/inett_studio/sqx/universal/universal.c b/keyboards/inett_studio/sqx/universal/universal.c index 42d99330d5..dd431a7f45 100644 --- a/keyboards/inett_studio/sqx/universal/universal.c +++ b/keyboards/inett_studio/sqx/universal/universal.c @@ -20,7 +20,7 @@ #include "universal.h" #ifdef RGB_MATRIX_ENABLE -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { /* Refer to IS31 manual for these locations * driver * | R location diff --git a/keyboards/k_type/is31fl3733-dual.h b/keyboards/k_type/is31fl3733-dual.h index 272bcdc417..aab170a3fd 100644 --- a/keyboards/k_type/is31fl3733-dual.h +++ b/keyboards/k_type/is31fl3733-dual.h @@ -28,7 +28,7 @@ typedef struct is31_led { uint8_t b; } __attribute__((packed)) is31_led; -extern const is31_led g_is31_leds[DRIVER_LED_TOTAL]; +extern const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL]; void IS31FL3733_init(uint8_t bus, uint8_t addr, uint8_t sync); bool IS31FL3733_write_register(uint8_t index, uint8_t addr, uint8_t reg, uint8_t data); diff --git a/keyboards/k_type/k_type.c b/keyboards/k_type/k_type.c index 61c5881454..924862277f 100644 --- a/keyboards/k_type/k_type.c +++ b/keyboards/k_type/k_type.c @@ -23,7 +23,7 @@ along with this program. If not, see . #include "is31fl3733-dual.h" -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { { 0, B_1, A_1, C_1 }, { 0, B_2, A_2, C_2 }, { 0, B_3, A_3, C_3 }, diff --git a/keyboards/kbdfans/bella/rgb/rgb.c b/keyboards/kbdfans/bella/rgb/rgb.c index e197d9b538..17cf992146 100644 --- a/keyboards/kbdfans/bella/rgb/rgb.c +++ b/keyboards/kbdfans/bella/rgb/rgb.c @@ -15,7 +15,7 @@ */ #include "rgb.h" #ifdef RGB_MATRIX_ENABLE -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { {0, CS18_SW1, CS17_SW1, CS16_SW1}, /* RGB6 */ {0, CS18_SW3, CS17_SW3, CS16_SW3}, /* RGB32 */ {0, CS18_SW4, CS17_SW4, CS16_SW4}, /* RGB45 */ diff --git a/keyboards/kbdfans/bella/rgb_iso/rgb_iso.c b/keyboards/kbdfans/bella/rgb_iso/rgb_iso.c index 1a853ac8af..0c431b1543 100644 --- a/keyboards/kbdfans/bella/rgb_iso/rgb_iso.c +++ b/keyboards/kbdfans/bella/rgb_iso/rgb_iso.c @@ -15,7 +15,7 @@ */ #include "rgb_iso.h" #ifdef RGB_MATRIX_ENABLE -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { {0, CS18_SW1, CS17_SW1, CS16_SW1}, /* RGB6 */ {0, CS18_SW3, CS17_SW3, CS16_SW3}, /* RGB32 */ {0, CS18_SW4, CS17_SW4, CS16_SW4}, /* RGB45 */ diff --git a/keyboards/kbdfans/kbd67/mkiirgb/mkiirgb.c b/keyboards/kbdfans/kbd67/mkiirgb/mkiirgb.c index 323cb23848..2826c08988 100644 --- a/keyboards/kbdfans/kbd67/mkiirgb/mkiirgb.c +++ b/keyboards/kbdfans/kbd67/mkiirgb/mkiirgb.c @@ -1,6 +1,6 @@ #include "mkiirgb.h" #ifdef RGB_MATRIX_ENABLE -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { {0, C8_8, C7_8, C6_8}, // LA17 {0, C9_8, C7_7, C6_7}, // LA16 diff --git a/keyboards/kbdfans/kbdmini/kbdmini.c b/keyboards/kbdfans/kbdmini/kbdmini.c index 0e0df2f9af..799803c6fa 100644 --- a/keyboards/kbdfans/kbdmini/kbdmini.c +++ b/keyboards/kbdfans/kbdmini/kbdmini.c @@ -1,6 +1,6 @@ #include "kbdmini.h" -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { { 0, B_9, A_9, C_9 }, //LA33 { 0, B_10, A_10, C_10 }, //LA37 { 0, B_11, A_11, C_11 }, //LA41 diff --git a/keyboards/kbdfans/maja/maja.c b/keyboards/kbdfans/maja/maja.c index a0afcbda8a..9619a84b48 100755 --- a/keyboards/kbdfans/maja/maja.c +++ b/keyboards/kbdfans/maja/maja.c @@ -1,6 +1,6 @@ #include "maja.h" -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { {0, C2_1, C3_1, C4_1}, // LA0 {0, C1_1, C3_2, C4_2}, // LA1 {0, C1_2, C2_2, C4_3}, // LA2 diff --git a/keyboards/keychron/q1/q1.c b/keyboards/keychron/q1/q1.c index 520e6e4c57..6beb96e7eb 100644 --- a/keyboards/keychron/q1/q1.c +++ b/keyboards/keychron/q1/q1.c @@ -33,7 +33,7 @@ bool dip_switch_update_kb(uint8_t index, bool active) { return true; } -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { /* Refer to IS31 manual for these locations * driver * | R location diff --git a/keyboards/latin17rgb/latin17rgb.c b/keyboards/latin17rgb/latin17rgb.c index 8d9eaae8ae..f7bbe125c2 100644 --- a/keyboards/latin17rgb/latin17rgb.c +++ b/keyboards/latin17rgb/latin17rgb.c @@ -17,7 +17,7 @@ #ifdef RGB_MATRIX_ENABLE -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { /* Refer to IS31 manual for these locations * driver * | R location diff --git a/keyboards/latin60rgb/latin60rgb.c b/keyboards/latin60rgb/latin60rgb.c index cdd6fed44d..fe5d2eea8f 100644 --- a/keyboards/latin60rgb/latin60rgb.c +++ b/keyboards/latin60rgb/latin60rgb.c @@ -16,7 +16,7 @@ #include "latin60rgb.h" #ifdef RGB_MATRIX_ENABLE -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { { 0, K_13, J_13, L_13 }, { 0, K_12, J_12, L_12 }, { 0, K_11, J_11, L_11 }, diff --git a/keyboards/latin6rgb/latin6rgb.c b/keyboards/latin6rgb/latin6rgb.c index 76b39c86bb..9ea4721ecb 100644 --- a/keyboards/latin6rgb/latin6rgb.c +++ b/keyboards/latin6rgb/latin6rgb.c @@ -17,7 +17,7 @@ #ifdef RGB_MATRIX_ENABLE -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { /* Refer to IS31 manual for these locations * driver * | R location diff --git a/keyboards/matrix/m20add/rgb_ring.c b/keyboards/matrix/m20add/rgb_ring.c index fa70dea7eb..3a8af7cd3b 100644 --- a/keyboards/matrix/m20add/rgb_ring.c +++ b/keyboards/matrix/m20add/rgb_ring.c @@ -30,7 +30,7 @@ #endif // rgb ring leds setting -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { /* Refer to IS31 manual for these locations * driver * | R location diff --git a/keyboards/matrix/noah/noah.c b/keyboards/matrix/noah/noah.c index 1e2f4bb7d9..6b624b9e09 100644 --- a/keyboards/matrix/noah/noah.c +++ b/keyboards/matrix/noah/noah.c @@ -66,7 +66,7 @@ __attribute__((weak)) void matrix_scan_user(void) { } #ifdef RGB_MATRIX_ENABLE -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { /* Refer to IS31 manual for these locations * driver * | R location diff --git a/keyboards/mechlovin/adelais/rgb_led/rev2/rev2.c b/keyboards/mechlovin/adelais/rgb_led/rev2/rev2.c index 5087174b96..fe946169a7 100644 --- a/keyboards/mechlovin/adelais/rgb_led/rev2/rev2.c +++ b/keyboards/mechlovin/adelais/rgb_led/rev2/rev2.c @@ -17,7 +17,7 @@ #include "adelais.h" #ifdef RGB_MATRIX_ENABLE -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { {0, C2_1, C3_1, C4_1}, //D102-A0-0 {0, C5_1, C6_1, C7_1}, //D108-A1-1 diff --git a/keyboards/mechlovin/delphine/rgb_led/rgb_led.c b/keyboards/mechlovin/delphine/rgb_led/rgb_led.c index 6f3e3ec731..29b6d1f783 100644 --- a/keyboards/mechlovin/delphine/rgb_led/rgb_led.c +++ b/keyboards/mechlovin/delphine/rgb_led/rgb_led.c @@ -18,7 +18,7 @@ #ifdef RGB_MATRIX_ENABLE -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { // left CA {0, C5_2, C6_2, C7_2}, //D2-0 {0, C1_1, C3_2, C4_2}, //D20-1 diff --git a/keyboards/mechlovin/hannah60rgb/rev2/rev2.c b/keyboards/mechlovin/hannah60rgb/rev2/rev2.c index 05469a1bbe..8b30538cc2 100644 --- a/keyboards/mechlovin/hannah60rgb/rev2/rev2.c +++ b/keyboards/mechlovin/hannah60rgb/rev2/rev2.c @@ -17,7 +17,7 @@ #include "rev2.h" #ifdef RGB_MATRIX_ENABLE -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { /* Refer to IS31 manual for these locations * driver * | R location diff --git a/keyboards/mechlovin/infinity87/rgb_rev1/rgb_rev1.c b/keyboards/mechlovin/infinity87/rgb_rev1/rgb_rev1.c index f13fee8add..bd1fd8abf7 100644 --- a/keyboards/mechlovin/infinity87/rgb_rev1/rgb_rev1.c +++ b/keyboards/mechlovin/infinity87/rgb_rev1/rgb_rev1.c @@ -17,7 +17,7 @@ #include "rgb_rev1.h" #ifdef RGB_MATRIX_ENABLE -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { {0, CS34_SW1, CS35_SW1, CS36_SW1}, //D92-K00-0 {0, CS37_SW1, CS38_SW1, CS39_SW1}, //D94-K01-1 {0, CS31_SW1, CS32_SW1, CS33_SW1}, //D96-K02-2 diff --git a/keyboards/melgeek/mj61/rev1/rev1.c b/keyboards/melgeek/mj61/rev1/rev1.c index be58f57a95..e51c57548f 100644 --- a/keyboards/melgeek/mj61/rev1/rev1.c +++ b/keyboards/melgeek/mj61/rev1/rev1.c @@ -17,7 +17,7 @@ #include "mj61.h" #ifdef RGB_MATRIX_ENABLE -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { {0, CS12_SW1, CS11_SW1, CS10_SW1}, /* RGB1 */ {0, CS12_SW2, CS11_SW2, CS10_SW2}, /* RGB2 */ {0, CS12_SW3, CS11_SW3, CS10_SW3}, /* RGB3 */ diff --git a/keyboards/melgeek/mj61/rev2/rev2.c b/keyboards/melgeek/mj61/rev2/rev2.c index 236b003972..3f6b1bff77 100644 --- a/keyboards/melgeek/mj61/rev2/rev2.c +++ b/keyboards/melgeek/mj61/rev2/rev2.c @@ -19,7 +19,7 @@ #ifdef RGB_MATRIX_ENABLE -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { {0, CS9_SW1, CS8_SW1, CS7_SW1}, /* RGB1 */ {0, CS9_SW2, CS8_SW2, CS7_SW2}, /* RGB3 */ {0, CS9_SW3, CS8_SW3, CS7_SW3}, /* RGB4 */ diff --git a/keyboards/melgeek/mj63/rev1/rev1.c b/keyboards/melgeek/mj63/rev1/rev1.c index 34ff28d25f..a6ee8859b0 100644 --- a/keyboards/melgeek/mj63/rev1/rev1.c +++ b/keyboards/melgeek/mj63/rev1/rev1.c @@ -19,7 +19,7 @@ #ifdef RGB_MATRIX_ENABLE -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { {0, CS9_SW1, CS8_SW1, CS7_SW1}, /* RGB1 */ {0, CS9_SW2, CS8_SW2, CS7_SW2}, /* RGB2 */ {0, CS9_SW3, CS8_SW3, CS7_SW3}, /* RGB3 */ diff --git a/keyboards/melgeek/mj63/rev2/rev2.c b/keyboards/melgeek/mj63/rev2/rev2.c index c2379dabe9..8cacc689ae 100644 --- a/keyboards/melgeek/mj63/rev2/rev2.c +++ b/keyboards/melgeek/mj63/rev2/rev2.c @@ -19,7 +19,7 @@ #ifdef RGB_MATRIX_ENABLE -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { {0, CS9_SW1, CS8_SW1, CS7_SW1}, /* RGB1 */ {0, CS9_SW2, CS8_SW2, CS7_SW2}, /* RGB3 */ {0, CS9_SW3, CS8_SW3, CS7_SW3}, /* RGB4 */ diff --git a/keyboards/melgeek/mj64/rev1/rev1.c b/keyboards/melgeek/mj64/rev1/rev1.c index e01765b694..446ba779d0 100644 --- a/keyboards/melgeek/mj64/rev1/rev1.c +++ b/keyboards/melgeek/mj64/rev1/rev1.c @@ -18,7 +18,7 @@ #ifdef RGB_MATRIX_ENABLE -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { {0, CS9_SW1, CS8_SW1, CS7_SW1}, /* RGB1 */ {0, CS9_SW2, CS8_SW2, CS7_SW2}, /* RGB2 */ {0, CS9_SW3, CS8_SW3, CS7_SW3}, /* RGB3 */ diff --git a/keyboards/melgeek/mj64/rev2/rev2.c b/keyboards/melgeek/mj64/rev2/rev2.c index d5486b9086..444e8f60ac 100644 --- a/keyboards/melgeek/mj64/rev2/rev2.c +++ b/keyboards/melgeek/mj64/rev2/rev2.c @@ -18,7 +18,7 @@ #ifdef RGB_MATRIX_ENABLE -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { {0, CS9_SW1, CS8_SW1, CS7_SW1}, /* RGB1 */ {0, CS9_SW2, CS8_SW2, CS7_SW2}, /* RGB2 */ {0, CS9_SW3, CS8_SW3, CS7_SW3}, /* RGB3 */ diff --git a/keyboards/melgeek/mj64/rev3/rev3.c b/keyboards/melgeek/mj64/rev3/rev3.c index 03ed9fe007..2a1283ec70 100644 --- a/keyboards/melgeek/mj64/rev3/rev3.c +++ b/keyboards/melgeek/mj64/rev3/rev3.c @@ -18,7 +18,7 @@ #ifdef RGB_MATRIX_ENABLE -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { {0, CS9_SW1, CS8_SW1, CS7_SW1}, /* RGB1 */ {0, CS9_SW2, CS8_SW2, CS7_SW2}, /* RGB3 */ {0, CS9_SW3, CS8_SW3, CS7_SW3}, /* RGB4 */ diff --git a/keyboards/melgeek/mj65/rev3/rev3.c b/keyboards/melgeek/mj65/rev3/rev3.c index 43fae53a36..6335edd796 100644 --- a/keyboards/melgeek/mj65/rev3/rev3.c +++ b/keyboards/melgeek/mj65/rev3/rev3.c @@ -18,7 +18,7 @@ #ifdef RGB_MATRIX_ENABLE -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { {0, CS9_SW1, CS8_SW1, CS7_SW1}, /* RGB1 */ {0, CS9_SW2, CS8_SW2, CS7_SW2}, /* RGB2 */ {0, CS9_SW3, CS8_SW3, CS7_SW3}, /* RGB3 */ diff --git a/keyboards/melgeek/mojo75/rev1/rev1.c b/keyboards/melgeek/mojo75/rev1/rev1.c index 670116fcd6..07ae916da2 100644 --- a/keyboards/melgeek/mojo75/rev1/rev1.c +++ b/keyboards/melgeek/mojo75/rev1/rev1.c @@ -18,7 +18,7 @@ #ifdef RGB_MATRIX_ENABLE -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { {0, CS6_SW1, CS5_SW1, CS4_SW1}, /* RGB1 */ {0, CS6_SW2, CS5_SW2, CS4_SW2}, /* RGB2 */ {0, CS6_SW3, CS5_SW3, CS4_SW3}, /* RGB3 */ diff --git a/keyboards/melgeek/z70ultra/z70ultra.c b/keyboards/melgeek/z70ultra/z70ultra.c index 740720681a..552576cd7c 100644 --- a/keyboards/melgeek/z70ultra/z70ultra.c +++ b/keyboards/melgeek/z70ultra/z70ultra.c @@ -18,7 +18,7 @@ #ifdef RGB_MATRIX_ENABLE -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { {0, CS28_SW1, CS30_SW1, CS29_SW1}, /* RGB10 */ {0, CS28_SW2, CS30_SW2, CS29_SW2}, /* RGB11 */ {0, CS28_SW3, CS30_SW3, CS29_SW3}, /* RGB12 */ diff --git a/keyboards/miller/gm862/gm862.c b/keyboards/miller/gm862/gm862.c index 5af66dd398..d67104838b 100644 --- a/keyboards/miller/gm862/gm862.c +++ b/keyboards/miller/gm862/gm862.c @@ -1,7 +1,7 @@ #include "gm862.h" #ifdef RGB_MATRIX_ENABLE -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { {0, B_1, A_1, C_1}, {0, B_2, A_2, C_2}, {0, B_3, A_3, C_3}, diff --git a/keyboards/moonlander/moonlander.c b/keyboards/moonlander/moonlander.c index d66b74d973..8688b9efa4 100644 --- a/keyboards/moonlander/moonlander.c +++ b/keyboards/moonlander/moonlander.c @@ -203,7 +203,7 @@ layer_state_t layer_state_set_kb(layer_state_t state) { #ifdef RGB_MATRIX_ENABLE // clang-format off -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { /* Refer to IS31 manual for these locations * driver * | R location diff --git a/keyboards/mt64rgb/mt64rgb.c b/keyboards/mt64rgb/mt64rgb.c index 73f0e562e7..a0b8e8da71 100644 --- a/keyboards/mt64rgb/mt64rgb.c +++ b/keyboards/mt64rgb/mt64rgb.c @@ -16,7 +16,7 @@ #include "mt64rgb.h" #ifdef RGB_MATRIX_ENABLE -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { /* Refer to IS31 manual for these locations * driver * | R location diff --git a/keyboards/mt84/mt84.c b/keyboards/mt84/mt84.c index e15a1ff951..9b00aa635e 100644 --- a/keyboards/mt84/mt84.c +++ b/keyboards/mt84/mt84.c @@ -16,7 +16,7 @@ #include "mt84.h" #ifdef RGB_MATRIX_ENABLE -const is31_led PROGMEM g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { /* Refer to IS31 manual for these locations * driver * | R location diff --git a/keyboards/opendeck/32/rev1/rev1.c b/keyboards/opendeck/32/rev1/rev1.c index 297af907e2..91f59a60b7 100644 --- a/keyboards/opendeck/32/rev1/rev1.c +++ b/keyboards/opendeck/32/rev1/rev1.c @@ -17,7 +17,7 @@ #include "rev1.h" #ifdef RGB_MATRIX_ENABLE -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { /* Refer to IS31 manual for these locations * driver * | R location diff --git a/keyboards/planck/ez/ez.c b/keyboards/planck/ez/ez.c index 5c68726a01..27cb2a1d1d 100644 --- a/keyboards/planck/ez/ez.c +++ b/keyboards/planck/ez/ez.c @@ -21,7 +21,7 @@ keyboard_config_t keyboard_config; #ifdef RGB_MATRIX_ENABLE -const is31_led PROGMEM g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { /* Refer to IS31 manual for these locations * driver * | R location diff --git a/keyboards/planck/light/light.c b/keyboards/planck/light/light.c index 896ec44587..3a53e39985 100644 --- a/keyboards/planck/light/light.c +++ b/keyboards/planck/light/light.c @@ -16,7 +16,7 @@ #include "light.h" -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { /* Refer to IS31 manual for these locations * driver * | R location diff --git a/keyboards/terrazzo/terrazzo.c b/keyboards/terrazzo/terrazzo.c index e6ba1f6c39..19ac6be491 100644 --- a/keyboards/terrazzo/terrazzo.c +++ b/keyboards/terrazzo/terrazzo.c @@ -21,7 +21,7 @@ #include "print.h" #include "quantum.h" -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { /* Refer to IS31 manual for these locations * https://cdn-learn.adafruit.com/downloads/pdf/adafruit-15x7-7x15-charlieplex-led-matrix-charliewing-featherwing.pdf */ diff --git a/keyboards/tkc/portico/portico.c b/keyboards/tkc/portico/portico.c index a65a85d242..e3d3a14880 100644 --- a/keyboards/tkc/portico/portico.c +++ b/keyboards/tkc/portico/portico.c @@ -19,7 +19,7 @@ along with this program. If not, see . #ifdef RGB_MATRIX_ENABLE -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { { 0, C2_1, C3_1, C4_1 }, { 0, C1_1, C3_2, C4_2 }, { 0, C1_2, C2_2, C4_3 }, diff --git a/keyboards/whitefox/whitefox.c b/keyboards/whitefox/whitefox.c index f10f0fd5c4..b17af15127 100644 --- a/keyboards/whitefox/whitefox.c +++ b/keyboards/whitefox/whitefox.c @@ -18,7 +18,7 @@ along with this program. If not, see . #include "whitefox.h" #ifdef LED_MATRIX_ENABLE -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { // The numbers in the comments are the led numbers DXX on the PCB /* Refer to IS31 manual for these locations * driver diff --git a/keyboards/wilba_tech/wt_rgb_backlight.c b/keyboards/wilba_tech/wt_rgb_backlight.c index e0359daab4..77613a3338 100644 --- a/keyboards/wilba_tech/wt_rgb_backlight.c +++ b/keyboards/wilba_tech/wt_rgb_backlight.c @@ -158,7 +158,7 @@ uint32_t g_any_key_hit = 0; // ADDR_2 is not needed. it is here as a dummy #define ISSI_ADDR_1 0x50 -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { /* Refer to IS31 manual for these locations * driver * | R location @@ -239,7 +239,7 @@ const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { #define ISSI_ADDR_1 0x50 #define ISSI_ADDR_2 0x52 -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { /* Refer to IS31 manual for these locations * driver * | R location @@ -382,7 +382,7 @@ const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { // set to 0 for write, 1 for read (as per I2C protocol) #define ISSI_ADDR_1 0x74 -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { /* Refer to IS31 manual for these locations * driver * | R location @@ -414,7 +414,7 @@ const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { #define ISSI_ADDR_2 0x76 // 11101[10] <- SDA #define ISSI_ADDR_3 0x75 // 11101[01] <- SCL -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { /* Refer to IS31 manual for these locations * driver * | R location @@ -541,7 +541,7 @@ const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { #define ISSI_ADDR_1 0x74 #define ISSI_ADDR_2 0x76 -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { /* Refer to IS31 manual for these locations * driver * | R location @@ -622,7 +622,7 @@ const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { #define ISSI_ADDR_1 0x74 #define ISSI_ADDR_2 0x77 -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { /* Refer to IS31 manual for these locations * driver * | R location @@ -709,7 +709,7 @@ const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { #define ISSI_ADDR_1 0x74 #define ISSI_ADDR_2 -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { {0, C1_9, C3_10, C4_10}, // LB1 {0, C1_10, C2_10, C4_11}, // LB2 {0, C1_11, C2_11, C3_11}, // LB3 @@ -729,7 +729,7 @@ const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { #define ISSI_ADDR_1 0x74 #define ISSI_ADDR_2 0x76 -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { /* Refer to IS31 manual for these locations * driver * | R location diff --git a/keyboards/xbows/knight/knight.c b/keyboards/xbows/knight/knight.c index 1a1aebf18f..539ecb653e 100644 --- a/keyboards/xbows/knight/knight.c +++ b/keyboards/xbows/knight/knight.c @@ -15,7 +15,7 @@ */ #include "knight.h" #ifdef RGB_MATRIX_ENABLE - const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { + const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { {0, C1_3, C2_3, C3_3}, // L01 {0, C1_4, C2_4, C3_4}, // L02 diff --git a/keyboards/xbows/knight_plus/knight_plus.c b/keyboards/xbows/knight_plus/knight_plus.c index f2cf5399b6..c5dd1a5fd6 100644 --- a/keyboards/xbows/knight_plus/knight_plus.c +++ b/keyboards/xbows/knight_plus/knight_plus.c @@ -15,7 +15,7 @@ */ #include "knight_plus.h" #ifdef RGB_MATRIX_ENABLE - const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { + const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { {0, C1_3, C2_3, C3_3}, // L01 {0, C1_4, C2_4, C3_4}, // L02 diff --git a/keyboards/xbows/nature/nature.c b/keyboards/xbows/nature/nature.c index f1b0615845..b7b10d5abb 100644 --- a/keyboards/xbows/nature/nature.c +++ b/keyboards/xbows/nature/nature.c @@ -15,7 +15,7 @@ */ #include "nature.h" #ifdef RGB_MATRIX_ENABLE - const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { + const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { {0, C1_3, C2_3, C3_3}, // L01 {0, C1_4, C2_4, C3_4}, // L02 diff --git a/keyboards/xbows/numpad/numpad.c b/keyboards/xbows/numpad/numpad.c index 0ab677c769..4e05473b67 100644 --- a/keyboards/xbows/numpad/numpad.c +++ b/keyboards/xbows/numpad/numpad.c @@ -15,7 +15,7 @@ */ #include "numpad.h" #ifdef RGB_MATRIX_ENABLE - const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { + const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { {0, C3_3, C2_3, C1_3}, // L01 {0, C3_4, C2_4, C1_4}, // L02 diff --git a/keyboards/xbows/woody/woody.c b/keyboards/xbows/woody/woody.c index 9821f5f655..1027e3ca37 100644 --- a/keyboards/xbows/woody/woody.c +++ b/keyboards/xbows/woody/woody.c @@ -1,6 +1,6 @@ #include "woody.h" #ifdef RGB_MATRIX_ENABLE -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { {0, C8_8, C7_8, C6_8}, // LA17 {0, C9_8, C7_7, C6_7}, // LA16 diff --git a/keyboards/xelus/dawn60/rev1_qmk/rev1_qmk.c b/keyboards/xelus/dawn60/rev1_qmk/rev1_qmk.c index c305ecae14..c6ddef0931 100644 --- a/keyboards/xelus/dawn60/rev1_qmk/rev1_qmk.c +++ b/keyboards/xelus/dawn60/rev1_qmk/rev1_qmk.c @@ -25,7 +25,7 @@ #ifdef RGB_MATRIX_ENABLE LED_TYPE rgb_matrix_ws2812_array[WS2812_LED_TOTAL]; -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { /* Refer to IS31 manual for these locations * driver * | R location diff --git a/keyboards/xelus/pachi/rgb/rgb.c b/keyboards/xelus/pachi/rgb/rgb.c index ea9812d6b1..6f44b13e12 100644 --- a/keyboards/xelus/pachi/rgb/rgb.c +++ b/keyboards/xelus/pachi/rgb/rgb.c @@ -24,7 +24,7 @@ void matrix_io_delay(void) { __asm__ volatile("nop\nnop\nnop\n"); } #ifdef RGB_MATRIX_ENABLE #include #include "drivers/led/issi/is31fl3741.h" -const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { +const is31_led __flash g_is31_leds[DRIVER_LED_TOTAL] = { /* Refer to IS31 manual for these locations * driver * | R location diff --git a/tmk_core/common/progmem.h b/tmk_core/common/progmem.h index 3a7a169682..a70d8e299f 100644 --- a/tmk_core/common/progmem.h +++ b/tmk_core/common/progmem.h @@ -5,6 +5,7 @@ #else # include # define PROGMEM +# define __flash # define PSTR(x) x # define PGM_P const char* # define memcpy_P(dest, src, n) memcpy(dest, src, n) -- cgit v1.2.3