aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoryiancar <yiangosyiangou@cytanet.com.cy>2018-08-28 16:03:11 +0300
committerJack Humbert <jack.humb@gmail.com>2018-08-28 09:03:11 -0400
commitfdd0f915271f79b104aa5d216566bcc3fd134e85 (patch)
tree42656e9ebd132461b99d7b037563374e575053ae
parent2410f023598af65a551b42f569a2703a5621bdca (diff)
downloadqmk_firmware-fdd0f915271f79b104aa5d216566bcc3fd134e85.tar.gz
qmk_firmware-fdd0f915271f79b104aa5d216566bcc3fd134e85.zip
ISSI31FL3733 driver (#3679)
* ISSI31FL3733 driver - Addapted IS31 driver for the above driver * fix my branch * ISSI31FL3733 driver - Inclusion of above ISSI led driver * IS31fl3733 driver - Added correct function for control registers * Finalized support for ISSI31fl3733 led driver - Finalized and tested driver. - Modified i2c_master for arm due to declaration mistake. - Fixed spaces/tabs in quantum.h file. - Fixed spaces/tabs in common_features.mk file. - Removed unnecessary includes from rgb_matrix.c file. - Added local definitions for MIN and MAX macros in rgb_matrix.c file. - Adjusted chevron effect. - Added necessary define (RGB_3733_MATRIX_ENABLE) for makefile. - Added necessary C define (ISSI3733) to aid with inclusion of the correct header file. - Added documentation for the new driver. * Driver structure update - Changed rule includes to be more condensed (RGB_MATRIX_ENABLE = IS31FL3731) and (RGB_MATRIX_ENABLE = IS31FL3733) - Updated documentation - Reverted to the use of differently named functions for each driver and selecting the needed ones within rgb_matrix.c * ISSI Drivers refractoring - Moved issi drivers in a dedicated folder - Updated documentation * I2C library fix I released the special pins incorrectly before. It is now fixed.
-rw-r--r--common_features.mk40
-rw-r--r--docs/feature_rgb_matrix.md52
-rw-r--r--docs/hardware_drivers.md6
-rw-r--r--drivers/arm/i2c_master.c13
-rw-r--r--drivers/arm/i2c_master.h4
-rw-r--r--drivers/issi/is31fl3731.c (renamed from drivers/is31fl3731.c)50
-rw-r--r--drivers/issi/is31fl3731.h (renamed from drivers/is31fl3731.h)16
-rw-r--r--drivers/issi/is31fl3733.c253
-rw-r--r--drivers/issi/is31fl3733.h255
-rw-r--r--quantum/quantum.h40
-rw-r--r--quantum/rgb_matrix.c68
-rw-r--r--quantum/rgb_matrix.h8
12 files changed, 717 insertions, 88 deletions
diff --git a/common_features.mk b/common_features.mk
index b78f04d2a..e0d4ca297 100644
--- a/common_features.mk
+++ b/common_features.mk
@@ -61,8 +61,8 @@ endif
61 61
62ifeq ($(strip $(STENO_ENABLE)), yes) 62ifeq ($(strip $(STENO_ENABLE)), yes)
63 OPT_DEFS += -DSTENO_ENABLE 63 OPT_DEFS += -DSTENO_ENABLE
64 VIRTSER_ENABLE := yes 64 VIRTSER_ENABLE := yes
65 SRC += $(QUANTUM_DIR)/process_keycode/process_steno.c 65 SRC += $(QUANTUM_DIR)/process_keycode/process_steno.c
66endif 66endif
67 67
68ifeq ($(strip $(VIRTSER_ENABLE)), yes) 68ifeq ($(strip $(VIRTSER_ENABLE)), yes)
@@ -75,9 +75,9 @@ ifeq ($(strip $(FAUXCLICKY_ENABLE)), yes)
75endif 75endif
76 76
77ifeq ($(strip $(POINTING_DEVICE_ENABLE)), yes) 77ifeq ($(strip $(POINTING_DEVICE_ENABLE)), yes)
78 OPT_DEFS += -DPOINTING_DEVICE_ENABLE 78 OPT_DEFS += -DPOINTING_DEVICE_ENABLE
79 OPT_DEFS += -DMOUSE_ENABLE 79 OPT_DEFS += -DMOUSE_ENABLE
80 SRC += $(QUANTUM_DIR)/pointing_device.c 80 SRC += $(QUANTUM_DIR)/pointing_device.c
81endif 81endif
82 82
83ifeq ($(strip $(UCIS_ENABLE)), yes) 83ifeq ($(strip $(UCIS_ENABLE)), yes)
@@ -110,12 +110,14 @@ ifeq ($(strip $(RGBLIGHT_ENABLE)), yes)
110 ifeq ($(strip $(RGBLIGHT_CUSTOM_DRIVER)), yes) 110 ifeq ($(strip $(RGBLIGHT_CUSTOM_DRIVER)), yes)
111 OPT_DEFS += -DRGBLIGHT_CUSTOM_DRIVER 111 OPT_DEFS += -DRGBLIGHT_CUSTOM_DRIVER
112 else 112 else
113 SRC += ws2812.c 113 SRC += ws2812.c
114 endif 114 endif
115endif 115endif
116 116
117ifeq ($(strip $(RGB_MATRIX_ENABLE)), yes) 117ifeq ($(strip $(RGB_MATRIX_ENABLE)), yes)
118 OPT_DEFS += -DRGB_MATRIX_ENABLE 118 OPT_DEFS += -DRGB_MATRIX_ENABLE
119 OPT_DEFS += -DIS31FL3731
120 COMMON_VPATH += $(DRIVER_PATH)/issi
119 SRC += is31fl3731.c 121 SRC += is31fl3731.c
120 SRC += i2c_master.c 122 SRC += i2c_master.c
121 SRC += $(QUANTUM_DIR)/color.c 123 SRC += $(QUANTUM_DIR)/color.c
@@ -123,6 +125,28 @@ ifeq ($(strip $(RGB_MATRIX_ENABLE)), yes)
123 CIE1931_CURVE = yes 125 CIE1931_CURVE = yes
124endif 126endif
125 127
128ifeq ($(strip $(RGB_MATRIX_ENABLE)), IS31FL3731)
129 OPT_DEFS += -DRGB_MATRIX_ENABLE
130 OPT_DEFS += -DIS31FL3731
131 COMMON_VPATH += $(DRIVER_PATH)/issi
132 SRC += is31fl3731.c
133 SRC += i2c_master.c
134 SRC += $(QUANTUM_DIR)/color.c
135 SRC += $(QUANTUM_DIR)/rgb_matrix.c
136 CIE1931_CURVE = yes
137endif
138
139ifeq ($(strip $(RGB_MATRIX_ENABLE)), IS31FL3733)
140 OPT_DEFS += -DRGB_MATRIX_ENABLE
141 OPT_DEFS += -DIS31FL3733
142 COMMON_VPATH += $(DRIVER_PATH)/issi
143 SRC += is31fl3733.c
144 SRC += i2c_master.c
145 SRC += $(QUANTUM_DIR)/color.c
146 SRC += $(QUANTUM_DIR)/rgb_matrix.c
147 CIE1931_CURVE = yes
148endif
149
126ifeq ($(strip $(TAP_DANCE_ENABLE)), yes) 150ifeq ($(strip $(TAP_DANCE_ENABLE)), yes)
127 OPT_DEFS += -DTAP_DANCE_ENABLE 151 OPT_DEFS += -DTAP_DANCE_ENABLE
128 SRC += $(QUANTUM_DIR)/process_keycode/process_tap_dance.c 152 SRC += $(QUANTUM_DIR)/process_keycode/process_tap_dance.c
@@ -169,7 +193,7 @@ ifeq ($(strip $(BACKLIGHT_ENABLE)), yes)
169 ifeq ($(strip $(VISUALIZER_ENABLE)), yes) 193 ifeq ($(strip $(VISUALIZER_ENABLE)), yes)
170 CIE1931_CURVE = yes 194 CIE1931_CURVE = yes
171 endif 195 endif
172 ifeq ($(strip $(BACKLIGHT_CUSTOM_DRIVER)), yes) 196 ifeq ($(strip $(BACKLIGHT_CUSTOM_DRIVER)), yes)
173 OPT_DEFS += -DBACKLIGHT_CUSTOM_DRIVER 197 OPT_DEFS += -DBACKLIGHT_CUSTOM_DRIVER
174 endif 198 endif
175endif 199endif
@@ -200,7 +224,7 @@ endif
200 224
201ifeq ($(strip $(HD44780_ENABLE)), yes) 225ifeq ($(strip $(HD44780_ENABLE)), yes)
202 SRC += drivers/avr/hd44780.c 226 SRC += drivers/avr/hd44780.c
203 OPT_DEFS += -DHD44780_ENABLE 227 OPT_DEFS += -DHD44780_ENABLE
204endif 228endif
205 229
206QUANTUM_SRC:= \ 230QUANTUM_SRC:= \
diff --git a/docs/feature_rgb_matrix.md b/docs/feature_rgb_matrix.md
index ed33c7ea4..4f827f8dc 100644
--- a/docs/feature_rgb_matrix.md
+++ b/docs/feature_rgb_matrix.md
@@ -1,8 +1,12 @@
1# RGB Matrix Lighting 1# RGB Matrix Lighting
2 2
3## Driver configuration
4
5### IS31FL3731
6
3There is basic support for addressable RGB matrix lighting with the I2C IS31FL3731 RGB controller. To enable it, add this to your `rules.mk`: 7There is basic support for addressable RGB matrix lighting with the I2C IS31FL3731 RGB controller. To enable it, add this to your `rules.mk`:
4 8
5 RGB_MATRIX_ENABLE = yes 9 RGB_MATRIX_ENABLE = IS31FL3731
6 10
7Configure the hardware via your `config.h`: 11Configure the hardware via your `config.h`:
8 12
@@ -36,7 +40,51 @@ Define these arrays listing all the LEDs in your `<keyboard>.c`:
36 .... 40 ....
37 } 41 }
38 42
39Where `Cx_y` is the location of the LED in the matrix defined by [the datasheet](http://www.issi.com/WW/pdf/31FL3731.pdf). The `driver` is the index of the driver you defined in your `config.h` (`0` or `1` right now). 43Where `Cx_y` is the location of the LED in the matrix defined by [the datasheet](http://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` or `1` right now).
44
45### IS31FL3733
46
47There is basic support for addressable RGB matrix lighting with the I2C IS31FL3733 RGB controller. To enable it, add this to your `rules.mk`:
48
49 RGB_MATRIX_ENABLE = IS31FL3733
50
51Configure the hardware via your `config.h`:
52
53 // This is a 7-bit address, that gets left-shifted and bit 0
54 // set to 0 for write, 1 for read (as per I2C protocol)
55 // The address will vary depending on your wiring:
56 // 00 <-> GND
57 // 01 <-> SCL
58 // 10 <-> SDA
59 // 11 <-> VCC
60 // ADDR1 represents A1:A0 of the 7-bit address.
61 // ADDR2 represents A3:A2 of the 7-bit address.
62 // The result is: 0b101(ADDR2)(ADDR1)
63 #define DRIVER_ADDR_1 0b1010000
64 #define DRIVER_ADDR_2 0b1010000 // this is here for compliancy reasons.
65
66 #define DRIVER_COUNT 1
67 #define DRIVER_1_LED_TOTAL 64
68 #define DRIVER_LED_TOTAL DRIVER_1_LED_TOTAL
69
70Currently only a single drivers is supported, but it would be trivial to support all 4 combinations. For now define `DRIVER_ADDR_2` as `DRIVER_ADDR_1`
71
72Define these arrays listing all the LEDs in your `<keyboard>.c`:
73
74 const is31_led g_is31_leds[DRIVER_LED_TOTAL] = {
75 /* Refer to IS31 manual for these locations
76 * driver
77 * | R location
78 * | | G location
79 * | | | B location
80 * | | | | */
81 {0, B_1, A_1, C_1},
82 ....
83 }
84
85Where `X_Y` is the location of the LED in the matrix defined by [the datasheet](http://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` (Only `0` right now).
86
87From this point forward the configuration is the same for all the drivers.
40 88
41 const rgb_led g_rgb_leds[DRIVER_LED_TOTAL] = { 89 const rgb_led g_rgb_leds[DRIVER_LED_TOTAL] = {
42 /* {row | col << 4} 90 /* {row | col << 4}
diff --git a/docs/hardware_drivers.md b/docs/hardware_drivers.md
index 336bc908e..4c1266f22 100644
--- a/docs/hardware_drivers.md
+++ b/docs/hardware_drivers.md
@@ -26,6 +26,10 @@ You can make use of uGFX within QMK to drive character and graphic LCD's, LED ar
26 26
27Support for WS2811/WS2812{a,b,c} LED's. For more information see the [RGB Light](feature_rgblight.md) page. 27Support for WS2811/WS2812{a,b,c} LED's. For more information see the [RGB Light](feature_rgblight.md) page.
28 28
29## IS31FL3731 (AVR Only) 29## IS31FL3731
30 30
31Support for up to 2 drivers. Each driver impliments 2 charlieplex matrices to individually address LEDs using I2C. This allows up to 144 same color LEDs or 32 RGB LEDs. For more information on how to setup the driver see the [RGB Matrix](feature_rgb_matrix.md) page. 31Support for up to 2 drivers. Each driver impliments 2 charlieplex matrices to individually address LEDs using I2C. This allows up to 144 same color LEDs or 32 RGB LEDs. For more information on how to setup the driver see the [RGB Matrix](feature_rgb_matrix.md) page.
32
33## IS31FL3733
34
35Support for up to a single driver with room for expansion. Each driver can control 192 individual LEDs or 64 RGB LEDs. For more information on how to setup the driver see the [RGB Matrix](feature_rgb_matrix.md) page. \ No newline at end of file
diff --git a/drivers/arm/i2c_master.c b/drivers/arm/i2c_master.c
index 2fdd9f65e..2a7badd35 100644
--- a/drivers/arm/i2c_master.c
+++ b/drivers/arm/i2c_master.c
@@ -15,12 +15,14 @@
15 * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */ 16 */
17 17
18/* This library follows the convention of the AVR i2c_master library. 18/* This library is only valid for STM32 processors.
19 * This library follows the convention of the AVR i2c_master library.
19 * As a result addresses are expected to be already shifted (addr << 1). 20 * As a result addresses are expected to be already shifted (addr << 1).
20 * I2CD1 is the default driver which corresponds to pins B6 and B7. This 21 * I2CD1 is the default driver which corresponds to pins B6 and B7. This
21 * can be changed. 22 * can be changed.
22 * Please ensure that HAL_USE_I2C is TRUE in the halconf.h file and that 23 * Please ensure that HAL_USE_I2C is TRUE in the halconf.h file and that
23 * STM32_I2C_USE_I2C1 is TRUE in the mcuconf.h file. 24 * STM32_I2C_USE_I2C1 is TRUE in the mcuconf.h file. Pins B6 and B7 are used
25 * but using any other I2C pins should be trivial.
24 */ 26 */
25 27
26#include "i2c_master.h" 28#include "i2c_master.h"
@@ -41,7 +43,7 @@ static const I2CConfig i2cconfig = {
41 43
42void i2c_init(void) 44void i2c_init(void)
43{ 45{
44 palSetGroupMode(GPIOB,6,7, PAL_MODE_INPUT); // Try releasing special pins for a short time 46 palSetGroupMode(GPIOB, GPIOB_PIN6 | GPIOB_PIN7, 0, PAL_MODE_INPUT); // Try releasing special pins for a short time
45 chThdSleepMilliseconds(10); 47 chThdSleepMilliseconds(10);
46 48
47 palSetPadMode(GPIOB, 6, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN | PAL_STM32_PUPDR_PULLUP); 49 palSetPadMode(GPIOB, 6, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN | PAL_STM32_PUPDR_PULLUP);
@@ -82,12 +84,12 @@ uint8_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t l
82 { 84 {
83 complete_packet[i+1] = data[i]; 85 complete_packet[i+1] = data[i];
84 } 86 }
85 complete_packet[0] = regaddr 87 complete_packet[0] = regaddr;
86 88
87 return i2cMasterTransmitTimeout(&I2C_DRIVER, (i2c_address >> 1), complete_packet, length + 1, 0, 0, MS2ST(timeout)); 89 return i2cMasterTransmitTimeout(&I2C_DRIVER, (i2c_address >> 1), complete_packet, length + 1, 0, 0, MS2ST(timeout));
88} 90}
89 91
90uint8_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout) 92uint8_t i2c_readReg(uint8_t devaddr, uint8_t* regaddr, uint8_t* data, uint16_t length, uint16_t timeout)
91{ 93{
92 i2c_address = devaddr; 94 i2c_address = devaddr;
93 i2cStart(&I2C_DRIVER, &i2cconfig); 95 i2cStart(&I2C_DRIVER, &i2cconfig);
@@ -97,7 +99,6 @@ uint8_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t le
97// This is usually not needed. It releases the driver to allow pins to become GPIO again. 99// This is usually not needed. It releases the driver to allow pins to become GPIO again.
98uint8_t i2c_stop(uint16_t timeout) 100uint8_t i2c_stop(uint16_t timeout)
99{ 101{
100 i2c_address = address;
101 i2cStop(&I2C_DRIVER); 102 i2cStop(&I2C_DRIVER);
102 return 0; 103 return 0;
103} 104}
diff --git a/drivers/arm/i2c_master.h b/drivers/arm/i2c_master.h
index 9d51245be..591fa7f77 100644
--- a/drivers/arm/i2c_master.h
+++ b/drivers/arm/i2c_master.h
@@ -35,5 +35,5 @@ uint8_t i2c_start(uint8_t address);
35uint8_t i2c_transmit(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout); 35uint8_t i2c_transmit(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout);
36uint8_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout); 36uint8_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout);
37uint8_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout); 37uint8_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout);
38uint8_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout); 38uint8_t i2c_readReg(uint8_t devaddr, uint8_t* regaddr, uint8_t* data, uint16_t length, uint16_t timeout);
39void i2c_stop(void); 39uint8_t i2c_stop(uint16_t timeout);
diff --git a/drivers/is31fl3731.c b/drivers/issi/is31fl3731.c
index 0524feb49..4d0d6b8a5 100644
--- a/drivers/is31fl3731.c
+++ b/drivers/issi/is31fl3731.c
@@ -91,7 +91,7 @@ bool g_led_control_registers_update_required = false;
91// 0x10 - R16,R15,R14,R13,R12,R11,R10,R09 91// 0x10 - R16,R15,R14,R13,R12,R11,R10,R09
92 92
93 93
94void IS31_write_register( uint8_t addr, uint8_t reg, uint8_t data ) 94void IS31FL3731_write_register( uint8_t addr, uint8_t reg, uint8_t data )
95{ 95{
96 g_twi_transfer_buffer[0] = reg; 96 g_twi_transfer_buffer[0] = reg;
97 g_twi_transfer_buffer[1] = data; 97 g_twi_transfer_buffer[1] = data;
@@ -106,7 +106,7 @@ void IS31_write_register( uint8_t addr, uint8_t reg, uint8_t data )
106 #endif 106 #endif
107} 107}
108 108
109void IS31_write_pwm_buffer( uint8_t addr, uint8_t *pwm_buffer ) 109void IS31FL3731_write_pwm_buffer( uint8_t addr, uint8_t *pwm_buffer )
110{ 110{
111 // assumes bank is already selected 111 // assumes bank is already selected
112 112
@@ -135,7 +135,7 @@ void IS31_write_pwm_buffer( uint8_t addr, uint8_t *pwm_buffer )
135 } 135 }
136} 136}
137 137
138void IS31_init( uint8_t addr ) 138void IS31FL3731_init( uint8_t addr )
139{ 139{
140 // In order to avoid the LEDs being driven with garbage data 140 // In order to avoid the LEDs being driven with garbage data
141 // in the LED driver's PWM registers, first enable software shutdown, 141 // in the LED driver's PWM registers, first enable software shutdown,
@@ -143,10 +143,10 @@ void IS31_init( uint8_t addr )
143 // then disable software shutdown. 143 // then disable software shutdown.
144 144
145 // select "function register" bank 145 // select "function register" bank
146 IS31_write_register( addr, ISSI_COMMANDREGISTER, ISSI_BANK_FUNCTIONREG ); 146 IS31FL3731_write_register( addr, ISSI_COMMANDREGISTER, ISSI_BANK_FUNCTIONREG );
147 147
148 // enable software shutdown 148 // enable software shutdown
149 IS31_write_register( addr, ISSI_REG_SHUTDOWN, 0x00 ); 149 IS31FL3731_write_register( addr, ISSI_REG_SHUTDOWN, 0x00 );
150 // this delay was copied from other drivers, might not be needed 150 // this delay was copied from other drivers, might not be needed
151 #ifdef __AVR__ 151 #ifdef __AVR__
152 _delay_ms( 10 ); 152 _delay_ms( 10 );
@@ -155,47 +155,47 @@ void IS31_init( uint8_t addr )
155 #endif 155 #endif
156 156
157 // picture mode 157 // picture mode
158 IS31_write_register( addr, ISSI_REG_CONFIG, ISSI_REG_CONFIG_PICTUREMODE ); 158 IS31FL3731_write_register( addr, ISSI_REG_CONFIG, ISSI_REG_CONFIG_PICTUREMODE );
159 // display frame 0 159 // display frame 0
160 IS31_write_register( addr, ISSI_REG_PICTUREFRAME, 0x00 ); 160 IS31FL3731_write_register( addr, ISSI_REG_PICTUREFRAME, 0x00 );
161 // audio sync off 161 // audio sync off
162 IS31_write_register( addr, ISSI_REG_AUDIOSYNC, 0x00 ); 162 IS31FL3731_write_register( addr, ISSI_REG_AUDIOSYNC, 0x00 );
163 163
164 // select bank 0 164 // select bank 0
165 IS31_write_register( addr, ISSI_COMMANDREGISTER, 0 ); 165 IS31FL3731_write_register( addr, ISSI_COMMANDREGISTER, 0 );
166 166
167 // turn off all LEDs in the LED control register 167 // turn off all LEDs in the LED control register
168 for ( int i = 0x00; i <= 0x11; i++ ) 168 for ( int i = 0x00; i <= 0x11; i++ )
169 { 169 {
170 IS31_write_register( addr, i, 0x00 ); 170 IS31FL3731_write_register( addr, i, 0x00 );
171 } 171 }
172 172
173 // turn off all LEDs in the blink control register (not really needed) 173 // turn off all LEDs in the blink control register (not really needed)
174 for ( int i = 0x12; i <= 0x23; i++ ) 174 for ( int i = 0x12; i <= 0x23; i++ )
175 { 175 {
176 IS31_write_register( addr, i, 0x00 ); 176 IS31FL3731_write_register( addr, i, 0x00 );
177 } 177 }
178 178
179 // set PWM on all LEDs to 0 179 // set PWM on all LEDs to 0
180 for ( int i = 0x24; i <= 0xB3; i++ ) 180 for ( int i = 0x24; i <= 0xB3; i++ )
181 { 181 {
182 IS31_write_register( addr, i, 0x00 ); 182 IS31FL3731_write_register( addr, i, 0x00 );
183 } 183 }
184 184
185 // select "function register" bank 185 // select "function register" bank
186 IS31_write_register( addr, ISSI_COMMANDREGISTER, ISSI_BANK_FUNCTIONREG ); 186 IS31FL3731_write_register( addr, ISSI_COMMANDREGISTER, ISSI_BANK_FUNCTIONREG );
187 187
188 // disable software shutdown 188 // disable software shutdown
189 IS31_write_register( addr, ISSI_REG_SHUTDOWN, 0x01 ); 189 IS31FL3731_write_register( addr, ISSI_REG_SHUTDOWN, 0x01 );
190 190
191 // select bank 0 and leave it selected. 191 // select bank 0 and leave it selected.
192 // most usage after initialization is just writing PWM buffers in bank 0 192 // most usage after initialization is just writing PWM buffers in bank 0
193 // as there's not much point in double-buffering 193 // as there's not much point in double-buffering
194 IS31_write_register( addr, ISSI_COMMANDREGISTER, 0 ); 194 IS31FL3731_write_register( addr, ISSI_COMMANDREGISTER, 0 );
195 195
196} 196}
197 197
198void IS31_set_color( int index, uint8_t red, uint8_t green, uint8_t blue ) 198void IS31FL3731_set_color( int index, uint8_t red, uint8_t green, uint8_t blue )
199{ 199{
200 if ( index >= 0 && index < DRIVER_LED_TOTAL ) { 200 if ( index >= 0 && index < DRIVER_LED_TOTAL ) {
201 is31_led led = g_is31_leds[index]; 201 is31_led led = g_is31_leds[index];
@@ -208,15 +208,15 @@ void IS31_set_color( int index, uint8_t red, uint8_t green, uint8_t blue )
208 } 208 }
209} 209}
210 210
211void IS31_set_color_all( uint8_t red, uint8_t green, uint8_t blue ) 211void IS31FL3731_set_color_all( uint8_t red, uint8_t green, uint8_t blue )
212{ 212{
213 for ( int i = 0; i < DRIVER_LED_TOTAL; i++ ) 213 for ( int i = 0; i < DRIVER_LED_TOTAL; i++ )
214 { 214 {
215 IS31_set_color( i, red, green, blue ); 215 IS31FL3731_set_color( i, red, green, blue );
216 } 216 }
217} 217}
218 218
219void IS31_set_led_control_register( uint8_t index, bool red, bool green, bool blue ) 219void IS31FL3731_set_led_control_register( uint8_t index, bool red, bool green, bool blue )
220{ 220{
221 is31_led led = g_is31_leds[index]; 221 is31_led led = g_is31_leds[index];
222 222
@@ -247,24 +247,24 @@ void IS31_set_led_control_register( uint8_t index, bool red, bool green, bool bl
247 247
248} 248}
249 249
250void IS31_update_pwm_buffers( uint8_t addr1, uint8_t addr2 ) 250void IS31FL3731_update_pwm_buffers( uint8_t addr1, uint8_t addr2 )
251{ 251{
252 if ( g_pwm_buffer_update_required ) 252 if ( g_pwm_buffer_update_required )
253 { 253 {
254 IS31_write_pwm_buffer( addr1, g_pwm_buffer[0] ); 254 IS31FL3731_write_pwm_buffer( addr1, g_pwm_buffer[0] );
255 IS31_write_pwm_buffer( addr2, g_pwm_buffer[1] ); 255 IS31FL3731_write_pwm_buffer( addr2, g_pwm_buffer[1] );
256 } 256 }
257 g_pwm_buffer_update_required = false; 257 g_pwm_buffer_update_required = false;
258} 258}
259 259
260void IS31_update_led_control_registers( uint8_t addr1, uint8_t addr2 ) 260void IS31FL3731_update_led_control_registers( uint8_t addr1, uint8_t addr2 )
261{ 261{
262 if ( g_led_control_registers_update_required ) 262 if ( g_led_control_registers_update_required )
263 { 263 {
264 for ( int i=0; i<18; i++ ) 264 for ( int i=0; i<18; i++ )
265 { 265 {
266 IS31_write_register(addr1, i, g_led_control_registers[0][i] ); 266 IS31FL3731_write_register(addr1, i, g_led_control_registers[0][i] );
267 IS31_write_register(addr2, i, g_led_control_registers[1][i] ); 267 IS31FL3731_write_register(addr2, i, g_led_control_registers[1][i] );
268 } 268 }
269 } 269 }
270} 270}
diff --git a/drivers/is31fl3731.h b/drivers/issi/is31fl3731.h
index 9e195c240..f354a12db 100644
--- a/drivers/is31fl3731.h
+++ b/drivers/issi/is31fl3731.h
@@ -31,21 +31,21 @@ typedef struct is31_led {
31 31
32extern const is31_led g_is31_leds[DRIVER_LED_TOTAL]; 32extern const is31_led g_is31_leds[DRIVER_LED_TOTAL];
33 33
34void IS31_init( uint8_t addr ); 34void IS31FL3731_init( uint8_t addr );
35void IS31_write_register( uint8_t addr, uint8_t reg, uint8_t data ); 35void IS31FL3731_write_register( uint8_t addr, uint8_t reg, uint8_t data );
36void IS31_write_pwm_buffer( uint8_t addr, uint8_t *pwm_buffer ); 36void IS31FL3731_write_pwm_buffer( uint8_t addr, uint8_t *pwm_buffer );
37 37
38void IS31_set_color( int index, uint8_t red, uint8_t green, uint8_t blue ); 38void IS31FL3731_set_color( int index, uint8_t red, uint8_t green, uint8_t blue );
39void IS31_set_color_all( uint8_t red, uint8_t green, uint8_t blue ); 39void IS31FL3731_set_color_all( uint8_t red, uint8_t green, uint8_t blue );
40 40
41void IS31_set_led_control_register( uint8_t index, bool red, bool green, bool blue ); 41void IS31FL3731_set_led_control_register( uint8_t index, bool red, bool green, bool blue );
42 42
43// This should not be called from an interrupt 43// This should not be called from an interrupt
44// (eg. from a timer interrupt). 44// (eg. from a timer interrupt).
45// Call this while idle (in between matrix scans). 45// Call this while idle (in between matrix scans).
46// If the buffer is dirty, it will update the driver with the buffer. 46// If the buffer is dirty, it will update the driver with the buffer.
47void IS31_update_pwm_buffers( uint8_t addr1, uint8_t addr2 ); 47void IS31FL3731_update_pwm_buffers( uint8_t addr1, uint8_t addr2 );
48void IS31_update_led_control_registers( uint8_t addr1, uint8_t addr2 ); 48void IS31FL3731_update_led_control_registers( uint8_t addr1, uint8_t addr2 );
49 49
50#define C1_1 0x24 50#define C1_1 0x24
51#define C1_2 0x25 51#define C1_2 0x25
diff --git a/drivers/issi/is31fl3733.c b/drivers/issi/is31fl3733.c
new file mode 100644
index 000000000..4098b5468
--- /dev/null
+++ b/drivers/issi/is31fl3733.c
@@ -0,0 +1,253 @@
1/* Copyright 2017 Jason Williams
2 * Copyright 2018 Jack Humbert
3 * Copyright 2018 Yiancar
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#ifdef __AVR__
20#include <avr/interrupt.h>
21#include <avr/io.h>
22#include <util/delay.h>
23#else
24#include "wait.h"
25#endif
26
27#include "is31fl3733.h"
28#include <string.h>
29#include "i2c_master.h"
30#include "progmem.h"
31
32// This is a 7-bit address, that gets left-shifted and bit 0
33// set to 0 for write, 1 for read (as per I2C protocol)
34// The address will vary depending on your wiring:
35// 00 <-> GND
36// 01 <-> SCL
37// 10 <-> SDA
38// 11 <-> VCC
39// ADDR1 represents A1:A0 of the 7-bit address.
40// ADDR2 represents A3:A2 of the 7-bit address.
41// The result is: 0b101(ADDR2)(ADDR1)
42#define ISSI_ADDR_DEFAULT 0x50
43
44#define ISSI_COMMANDREGISTER 0xFD
45#define ISSI_COMMANDREGISTER_WRITELOCK 0xFE
46#define ISSI_INTERRUPTMASKREGISTER 0xF0
47#define ISSI_INTERRUPTSTATUSREGISTER 0xF1
48
49#define ISSI_PAGE_LEDCONTROL 0x00 //PG0
50#define ISSI_PAGE_PWM 0x01 //PG1
51#define ISSI_PAGE_AUTOBREATH 0x02 //PG2
52#define ISSI_PAGE_FUNCTION 0x03 //PG3
53
54#define ISSI_REG_CONFIGURATION 0x00 //PG3
55#define ISSI_REG_GLOBALCURRENT 0x01 //PG3
56#define ISSI_REG_RESET 0x11// PG3
57#define ISSI_REG_SWPULLUP 0x0F //PG3
58#define ISSI_REG_CSPULLUP 0x10 //PG3
59
60#ifndef ISSI_TIMEOUT
61 #define ISSI_TIMEOUT 100
62#endif
63
64#ifndef ISSI_PERSISTENCE
65 #define ISSI_PERSISTENCE 0
66#endif
67
68// Transfer buffer for TWITransmitData()
69uint8_t g_twi_transfer_buffer[20];
70
71// These buffers match the IS31FL3733 PWM registers.
72// The control buffers match the PG0 LED On/Off registers.
73// Storing them like this is optimal for I2C transfers to the registers.
74// We could optimize this and take out the unused registers from these
75// buffers and the transfers in IS31FL3733_write_pwm_buffer() but it's
76// probably not worth the extra complexity.
77uint8_t g_pwm_buffer[DRIVER_COUNT][192];
78bool g_pwm_buffer_update_required = false;
79
80uint8_t g_led_control_registers[DRIVER_COUNT][24] = { { 0 }, { 0 } };
81bool g_led_control_registers_update_required = false;
82
83void IS31FL3733_write_register( uint8_t addr, uint8_t reg, uint8_t data )
84{
85 g_twi_transfer_buffer[0] = reg;
86 g_twi_transfer_buffer[1] = data;
87
88 #if ISSI_PERSISTENCE > 0
89 for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) {
90 if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT) == 0)
91 break;
92 }
93 #else
94 i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, ISSI_TIMEOUT);
95 #endif
96}
97
98void IS31FL3733_write_pwm_buffer( uint8_t addr, uint8_t *pwm_buffer )
99{
100 // assumes PG1 is already selected
101
102 // transmit PWM registers in 12 transfers of 16 bytes
103 // g_twi_transfer_buffer[] is 20 bytes
104
105 // iterate over the pwm_buffer contents at 16 byte intervals
106 for ( int i = 0; i < 192; i += 16 ) {
107 g_twi_transfer_buffer[0] = i;
108 // copy the data from i to i+15
109 // device will auto-increment register for data after the first byte
110 // thus this sets registers 0x00-0x0F, 0x10-0x1F, etc. in one transfer
111 for ( int j = 0; j < 16; j++ ) {
112 g_twi_transfer_buffer[1 + j] = pwm_buffer[i + j];
113 }
114
115 #if ISSI_PERSISTENCE > 0
116 for (uint8_t i = 0; i < ISSI_PERSISTENCE; i++) {
117 if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT) == 0)
118 break;
119 }
120 #else
121 i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, ISSI_TIMEOUT);
122 #endif
123 }
124}
125
126void IS31FL3733_init( uint8_t addr )
127{
128 // In order to avoid the LEDs being driven with garbage data
129 // in the LED driver's PWM registers, shutdown is enabled last.
130 // Set up the mode and other settings, clear the PWM registers,
131 // then disable software shutdown.
132
133 // Unlock the command register.
134 IS31FL3733_write_register( addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5 );
135
136 // Select PG0
137 IS31FL3733_write_register( addr, ISSI_COMMANDREGISTER, ISSI_PAGE_LEDCONTROL );
138 // Turn off all LEDs.
139 for ( int i = 0x00; i <= 0x17; i++ )
140 {
141 IS31FL3733_write_register( addr, i, 0x00 );
142 }
143
144 // Unlock the command register.
145 IS31FL3733_write_register( addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5 );
146
147 // Select PG1
148 IS31FL3733_write_register( addr, ISSI_COMMANDREGISTER, ISSI_PAGE_PWM );
149 // Set PWM on all LEDs to 0
150 // No need to setup Breath registers to PWM as that is the default.
151 for ( int i = 0x00; i <= 0xBF; i++ )
152 {
153 IS31FL3733_write_register( addr, i, 0x00 );
154 }
155
156 // Unlock the command register.
157 IS31FL3733_write_register( addr, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5 );
158
159 // Select PG3
160 IS31FL3733_write_register( addr, ISSI_COMMANDREGISTER, ISSI_PAGE_FUNCTION );
161 // Set global current to maximum.
162 IS31FL3733_write_register( addr, ISSI_REG_GLOBALCURRENT, 0xFF );
163 // Disable software shutdown.
164 IS31FL3733_write_register( addr, ISSI_REG_CONFIGURATION, 0x01 );
165
166 // Wait 10ms to ensure the device has woken up.
167 #ifdef __AVR__
168 _delay_ms( 10 );
169 #else
170 wait_ms(10);
171 #endif
172}
173
174void IS31FL3733_set_color( int index, uint8_t red, uint8_t green, uint8_t blue )
175{
176 if ( index >= 0 && index < DRIVER_LED_TOTAL ) {
177 is31_led led = g_is31_leds[index];
178
179 g_pwm_buffer[led.driver][led.r] = red;
180 g_pwm_buffer[led.driver][led.g] = green;
181 g_pwm_buffer[led.driver][led.b] = blue;
182 g_pwm_buffer_update_required = true;
183 }
184}
185
186void IS31FL3733_set_color_all( uint8_t red, uint8_t green, uint8_t blue )
187{
188 for ( int i = 0; i < DRIVER_LED_TOTAL; i++ )
189 {
190 IS31FL3733_set_color( i, red, green, blue );
191 }
192}
193
194void IS31FL3733_set_led_control_register( uint8_t index, bool red, bool green, bool blue )
195{
196 is31_led led = g_is31_leds[index];
197
198 uint8_t control_register_r = led.r / 8;
199 uint8_t control_register_g = led.g / 8;
200 uint8_t control_register_b = led.b / 8;
201 uint8_t bit_r = led.r % 8;
202 uint8_t bit_g = led.g % 8;
203 uint8_t bit_b = led.b % 8;
204
205 if ( red ) {
206 g_led_control_registers[led.driver][control_register_r] |= (1 << bit_r);
207 } else {
208 g_led_control_registers[led.driver][control_register_r] &= ~(1 << bit_r);
209 }
210 if ( green ) {
211 g_led_control_registers[led.driver][control_register_g] |= (1 << bit_g);
212 } else {
213 g_led_control_registers[led.driver][control_register_g] &= ~(1 << bit_g);
214 }
215 if ( blue ) {
216 g_led_control_registers[led.driver][control_register_b] |= (1 << bit_b);
217 } else {
218 g_led_control_registers[led.driver][control_register_b] &= ~(1 << bit_b);
219 }
220
221 g_led_control_registers_update_required = true;
222
223}
224
225void IS31FL3733_update_pwm_buffers( uint8_t addr1, uint8_t addr2 )
226{
227 if ( g_pwm_buffer_update_required )
228 {
229 // Firstly we need to unlock the command register and select PG1
230 IS31FL3733_write_register( addr1, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5 );
231 IS31FL3733_write_register( addr1, ISSI_COMMANDREGISTER, ISSI_PAGE_PWM );
232
233 IS31FL3733_write_pwm_buffer( addr1, g_pwm_buffer[0] );
234 //IS31FL3733_write_pwm_buffer( addr2, g_pwm_buffer[1] );
235 }
236 g_pwm_buffer_update_required = false;
237}
238
239void IS31FL3733_update_led_control_registers( uint8_t addr1, uint8_t addr2 )
240{
241 if ( g_led_control_registers_update_required )
242 {
243 // Firstly we need to unlock the command register and select PG0
244 IS31FL3733_write_register( addr1, ISSI_COMMANDREGISTER_WRITELOCK, 0xC5 );
245 IS31FL3733_write_register( addr1, ISSI_COMMANDREGISTER, ISSI_PAGE_LEDCONTROL );
246 for ( int i=0; i<24; i++ )
247 {
248 IS31FL3733_write_register(addr1, i, g_led_control_registers[0][i] );
249 //IS31FL3733_write_register(addr2, i, g_led_control_registers[1][i] );
250 }
251 }
252}
253
diff --git a/drivers/issi/is31fl3733.h b/drivers/issi/is31fl3733.h
new file mode 100644
index 000000000..3d23b188a
--- /dev/null
+++ b/drivers/issi/is31fl3733.h
@@ -0,0 +1,255 @@
1/* Copyright 2017 Jason Williams
2 * Copyright 2018 Jack Humbert
3 * Copyright 2018 Yiancar
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19
20#ifndef IS31FL3733_DRIVER_H
21#define IS31FL3733_DRIVER_H
22
23#include <stdint.h>
24#include <stdbool.h>
25
26typedef struct is31_led {
27 uint8_t driver:2;
28 uint8_t r;
29 uint8_t g;
30 uint8_t b;
31} __attribute__((packed)) is31_led;
32
33extern const is31_led g_is31_leds[DRIVER_LED_TOTAL];
34
35void IS31FL3733_init( uint8_t addr );
36void IS31FL3733_write_register( uint8_t addr, uint8_t reg, uint8_t data );
37void IS31FL3733_write_pwm_buffer( uint8_t addr, uint8_t *pwm_buffer );
38
39void IS31FL3733_set_color( int index, uint8_t red, uint8_t green, uint8_t blue );
40void IS31FL3733_set_color_all( uint8_t red, uint8_t green, uint8_t blue );
41
42void IS31FL3733_set_led_control_register( uint8_t index, bool red, bool green, bool blue );
43
44// This should not be called from an interrupt
45// (eg. from a timer interrupt).
46// Call this while idle (in between matrix scans).
47// If the buffer is dirty, it will update the driver with the buffer.
48void IS31FL3733_update_pwm_buffers( uint8_t addr1, uint8_t addr2 );
49void IS31FL3733_update_led_control_registers( uint8_t addr1, uint8_t addr2 );
50
51#define A_1 0x00
52#define A_2 0x01
53#define A_3 0x02
54#define A_4 0x03
55#define A_5 0x04
56#define A_6 0x05
57#define A_7 0x06
58#define A_8 0x07
59#define A_9 0x08
60#define A_10 0x09
61#define A_11 0x0A
62#define A_12 0x0B
63#define A_13 0x0C
64#define A_14 0x0D
65#define A_15 0x0E
66#define A_16 0x0F
67
68#define B_1 0x10
69#define B_2 0x11
70#define B_3 0x12
71#define B_4 0x13
72#define B_5 0x14
73#define B_6 0x15
74#define B_7 0x16
75#define B_8 0x17
76#define B_9 0x18
77#define B_10 0x19
78#define B_11 0x1A
79#define B_12 0x1B
80#define B_13 0x1C
81#define B_14 0x1D
82#define B_15 0x1E
83#define B_16 0x1F
84
85#define C_1 0x20
86#define C_2 0x21
87#define C_3 0x22
88#define C_4 0x23
89#define C_5 0x24
90#define C_6 0x25
91#define C_7 0x26
92#define C_8 0x27
93#define C_9 0x28
94#define C_10 0x29
95#define C_11 0x2A
96#define C_12 0x2B
97#define C_13 0x2C
98#define C_14 0x2D
99#define C_15 0x2E
100#define C_16 0x2F
101
102#define D_1 0x30
103#define D_2 0x31
104#define D_3 0x32
105#define D_4 0x33
106#define D_5 0x34
107#define D_6 0x35
108#define D_7 0x36
109#define D_8 0x37
110#define D_9 0x38
111#define D_10 0x39
112#define D_11 0x3A
113#define D_12 0x3B
114#define D_13 0x3C
115#define D_14 0x3D
116#define D_15 0x3E
117#define D_16 0x3F
118
119#define E_1 0x40
120#define E_2 0x41
121#define E_3 0x42
122#define E_4 0x43
123#define E_5 0x44
124#define E_6 0x45
125#define E_7 0x46
126#define E_8 0x47
127#define E_9 0x48
128#define E_10 0x49
129#define E_11 0x4A
130#define E_12 0x4B
131#define E_13 0x4C
132#define E_14 0x4D
133#define E_15 0x4E
134#define E_16 0x4F
135
136#define F_1 0x50
137#define F_2 0x51
138#define F_3 0x52
139#define F_4 0x53
140#define F_5 0x54
141#define F_6 0x55
142#define F_7 0x56
143#define F_8 0x57
144#define F_9 0x58
145#define F_10 0x59
146#define F_11 0x5A
147#define F_12 0x5B
148#define F_13 0x5C
149#define F_14 0x5D
150#define F_15 0x5E
151#define F_16 0x5F
152
153#define G_1 0x60
154#define G_2 0x61
155#define G_3 0x62
156#define G_4 0x63
157#define G_5 0x64
158#define G_6 0x65
159#define G_7 0x66
160#define G_8 0x67
161#define G_9 0x68
162#define G_10 0x69
163#define G_11 0x6A
164#define G_12 0x6B
165#define G_13 0x6C
166#define G_14 0x6D
167#define G_15 0x6E
168#define G_16 0x6F
169
170#define H_1 0x70
171#define H_2 0x71
172#define H_3 0x72
173#define H_4 0x73
174#define H_5 0x74
175#define H_6 0x75
176#define H_7 0x76
177#define H_8 0x77
178#define H_9 0x78
179#define H_10 0x79
180#define H_11 0x7A
181#define H_12 0x7B
182#define H_13 0x7C
183#define H_14 0x7D
184#define H_15 0x7E
185#define H_16 0x7F
186
187#define I_1 0x80
188#define I_2 0x81
189#define I_3 0x82
190#define I_4 0x83
191#define I_5 0x84
192#define I_6 0x85
193#define I_7 0x86
194#define I_8 0x87
195#define I_9 0x88
196#define I_10 0x89
197#define I_11 0x8A
198#define I_12 0x8B
199#define I_13 0x8C
200#define I_14 0x8D
201#define I_15 0x8E
202#define I_16 0x8F
203
204#define J_1 0x90
205#define J_2 0x91
206#define J_3 0x92
207#define J_4 0x93
208#define J_5 0x94
209#define J_6 0x95
210#define J_7 0x96
211#define J_8 0x97
212#define J_9 0x98
213#define J_10 0x99
214#define J_11 0x9A
215#define J_12 0x9B
216#define J_13 0x9C
217#define J_14 0x9D
218#define J_15 0x9E
219#define J_16 0x9F
220
221#define K_1 0xA0
222#define K_2 0xA1
223#define K_3 0xA2
224#define K_4 0xA3
225#define K_5 0xA4
226#define K_6 0xA5
227#define K_7 0xA6
228#define K_8 0xA7
229#define K_9 0xA8
230#define K_10 0xA9
231#define K_11 0xAA
232#define K_12 0xAB
233#define K_13 0xAC
234#define K_14 0xAD
235#define K_15 0xAE
236#define K_16 0xAF
237
238#define L_1 0xB0
239#define L_2 0xB1
240#define L_3 0xB2
241#define L_4 0xB3
242#define L_5 0xB4
243#define L_6 0xB5
244#define L_7 0xB6
245#define L_8 0xB7
246#define L_9 0xB8
247#define L_10 0xB9
248#define L_11 0xBA
249#define L_12 0xBB
250#define L_13 0xBC
251#define L_14 0xBD
252#define L_15 0xBE
253#define L_16 0xBF
254
255#endif // IS31FL3733_DRIVER_H
diff --git a/quantum/quantum.h b/quantum/quantum.h
index 1db9846f0..b4e4de174 100644
--- a/quantum/quantum.h
+++ b/quantum/quantum.h
@@ -28,7 +28,7 @@
28 #include "backlight.h" 28 #include "backlight.h"
29#endif 29#endif
30#if !defined(RGBLIGHT_ENABLE) && !defined(RGB_MATRIX_ENABLE) 30#if !defined(RGBLIGHT_ENABLE) && !defined(RGB_MATRIX_ENABLE)
31 #include "rgb.h" 31 #include "rgb.h"
32#endif 32#endif
33#ifdef RGBLIGHT_ENABLE 33#ifdef RGBLIGHT_ENABLE
34 #include "rgblight.h" 34 #include "rgblight.h"
@@ -39,7 +39,7 @@
39#endif 39#endif
40 40
41#ifdef RGB_MATRIX_ENABLE 41#ifdef RGB_MATRIX_ENABLE
42 #include "rgb_matrix.h" 42 #include "rgb_matrix.h"
43#endif 43#endif
44 44
45#include "action_layer.h" 45#include "action_layer.h"
@@ -58,78 +58,78 @@
58extern uint32_t default_layer_state; 58extern uint32_t default_layer_state;
59 59
60#ifndef NO_ACTION_LAYER 60#ifndef NO_ACTION_LAYER
61 extern uint32_t layer_state; 61 extern uint32_t layer_state;
62#endif 62#endif
63 63
64#ifdef MIDI_ENABLE 64#ifdef MIDI_ENABLE
65#ifdef MIDI_ADVANCED 65#ifdef MIDI_ADVANCED
66 #include "process_midi.h" 66 #include "process_midi.h"
67#endif 67#endif
68#endif // MIDI_ENABLE 68#endif // MIDI_ENABLE
69 69
70#ifdef AUDIO_ENABLE 70#ifdef AUDIO_ENABLE
71 #include "audio.h" 71 #include "audio.h"
72 #include "process_audio.h" 72 #include "process_audio.h"
73 #ifdef AUDIO_CLICKY 73 #ifdef AUDIO_CLICKY
74 #include "process_clicky.h" 74 #include "process_clicky.h"
75 #endif // AUDIO_CLICKY 75 #endif // AUDIO_CLICKY
76#endif 76#endif
77 77
78#ifdef STENO_ENABLE 78#ifdef STENO_ENABLE
79 #include "process_steno.h" 79 #include "process_steno.h"
80#endif 80#endif
81 81
82#if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC)) 82#if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))
83 #include "process_music.h" 83 #include "process_music.h"
84#endif 84#endif
85 85
86#ifndef DISABLE_LEADER 86#ifndef DISABLE_LEADER
87 #include "process_leader.h" 87 #include "process_leader.h"
88#endif 88#endif
89 89
90#define DISABLE_CHORDING 90#define DISABLE_CHORDING
91#ifndef DISABLE_CHORDING 91#ifndef DISABLE_CHORDING
92 #include "process_chording.h" 92 #include "process_chording.h"
93#endif 93#endif
94 94
95#ifdef UNICODE_ENABLE 95#ifdef UNICODE_ENABLE
96 #include "process_unicode.h" 96 #include "process_unicode.h"
97#endif 97#endif
98 98
99#ifdef UCIS_ENABLE 99#ifdef UCIS_ENABLE
100 #include "process_ucis.h" 100 #include "process_ucis.h"
101#endif 101#endif
102 102
103#ifdef UNICODEMAP_ENABLE 103#ifdef UNICODEMAP_ENABLE
104 #include "process_unicodemap.h" 104 #include "process_unicodemap.h"
105#endif 105#endif
106 106
107#include "process_tap_dance.h" 107#include "process_tap_dance.h"
108 108
109#ifdef PRINTING_ENABLE 109#ifdef PRINTING_ENABLE
110 #include "process_printer.h" 110 #include "process_printer.h"
111#endif 111#endif
112 112
113#ifdef AUTO_SHIFT_ENABLE 113#ifdef AUTO_SHIFT_ENABLE
114 #include "process_auto_shift.h" 114 #include "process_auto_shift.h"
115#endif 115#endif
116 116
117#ifdef COMBO_ENABLE 117#ifdef COMBO_ENABLE
118 #include "process_combo.h" 118 #include "process_combo.h"
119#endif 119#endif
120 120
121#ifdef KEY_LOCK_ENABLE 121#ifdef KEY_LOCK_ENABLE
122 #include "process_key_lock.h" 122 #include "process_key_lock.h"
123#endif 123#endif
124 124
125#ifdef TERMINAL_ENABLE 125#ifdef TERMINAL_ENABLE
126 #include "process_terminal.h" 126 #include "process_terminal.h"
127#else 127#else
128 #include "process_terminal_nop.h" 128 #include "process_terminal_nop.h"
129#endif 129#endif
130 130
131#ifdef HD44780_ENABLE 131#ifdef HD44780_ENABLE
132 #include "hd44780.h" 132 #include "hd44780.h"
133#endif 133#endif
134 134
135#define STRINGIZE(z) #z 135#define STRINGIZE(z) #z
diff --git a/quantum/rgb_matrix.c b/quantum/rgb_matrix.c
index 70ad1a178..197bc1ac5 100644
--- a/quantum/rgb_matrix.c
+++ b/quantum/rgb_matrix.c
@@ -1,5 +1,6 @@
1/* Copyright 2017 Jason Williams 1/* Copyright 2017 Jason Williams
2 * Copyright 2017 Jack Humbert 2 * Copyright 2017 Jack Humbert
3 * Copyright 2018 Yiancar
3 * 4 *
4 * This program is free software: you can redistribute it and/or modify 5 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by 6 * it under the terms of the GNU General Public License as published by
@@ -17,18 +18,22 @@
17 18
18 19
19#include "rgb_matrix.h" 20#include "rgb_matrix.h"
20#include <avr/io.h>
21#include "i2c_master.h" 21#include "i2c_master.h"
22#include <util/delay.h>
23#include <avr/interrupt.h>
24#include "progmem.h" 22#include "progmem.h"
25#include "config.h" 23#include "config.h"
26#include "eeprom.h" 24#include "eeprom.h"
27#include "lufa.h"
28#include <math.h> 25#include <math.h>
29 26
30rgb_config_t rgb_matrix_config; 27rgb_config_t rgb_matrix_config;
31 28
29#ifndef MAX
30 #define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
31#endif
32
33#ifndef MIN
34 #define MIN(a,b) ((a) < (b)? (a): (b))
35#endif
36
32#ifndef RGB_DISABLE_AFTER_TIMEOUT 37#ifndef RGB_DISABLE_AFTER_TIMEOUT
33 #define RGB_DISABLE_AFTER_TIMEOUT 0 38 #define RGB_DISABLE_AFTER_TIMEOUT 0
34#endif 39#endif
@@ -106,16 +111,29 @@ void map_row_column_to_led( uint8_t row, uint8_t column, uint8_t *led_i, uint8_t
106} 111}
107 112
108void rgb_matrix_update_pwm_buffers(void) { 113void rgb_matrix_update_pwm_buffers(void) {
109 IS31_update_pwm_buffers( DRIVER_ADDR_1, DRIVER_ADDR_2 ); 114#ifdef IS31FL3731
110 IS31_update_led_control_registers( DRIVER_ADDR_1, DRIVER_ADDR_2 ); 115 IS31FL3731_update_pwm_buffers( DRIVER_ADDR_1, DRIVER_ADDR_2 );
116 IS31FL3731_update_led_control_registers( DRIVER_ADDR_1, DRIVER_ADDR_2 );
117#elif defined(IS31FL3733)
118 IS31FL3733_update_pwm_buffers( DRIVER_ADDR_1, DRIVER_ADDR_2 );
119 IS31FL3733_update_led_control_registers( DRIVER_ADDR_1, DRIVER_ADDR_2 );
120#endif
111} 121}
112 122
113void rgb_matrix_set_color( int index, uint8_t red, uint8_t green, uint8_t blue ) { 123void rgb_matrix_set_color( int index, uint8_t red, uint8_t green, uint8_t blue ) {
114 IS31_set_color( index, red, green, blue ); 124#ifdef IS31FL3731
125 IS31FL3731_set_color( index, red, green, blue );
126#elif defined(IS31FL3733)
127 IS31FL3733_set_color( index, red, green, blue );
128#endif
115} 129}
116 130
117void rgb_matrix_set_color_all( uint8_t red, uint8_t green, uint8_t blue ) { 131void rgb_matrix_set_color_all( uint8_t red, uint8_t green, uint8_t blue ) {
118 IS31_set_color_all( red, green, blue ); 132#ifdef IS31FL3731
133 IS31FL3731_set_color_all( red, green, blue );
134#elif defined(IS31FL3733)
135 IS31FL3733_set_color_all( red, green, blue );
136#endif
119} 137}
120 138
121bool process_rgb_matrix(uint16_t keycode, keyrecord_t *record) { 139bool process_rgb_matrix(uint16_t keycode, keyrecord_t *record) {
@@ -460,7 +478,7 @@ void rgb_matrix_rainbow_moving_chevron(void) {
460 for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) { 478 for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) {
461 led = g_rgb_leds[i]; 479 led = g_rgb_leds[i];
462 // uint8_t r = g_tick; 480 // uint8_t r = g_tick;
463 uint8_t r = 32; 481 uint8_t r = 128;
464 hsv.h = (1.5 * (rgb_matrix_config.speed == 0 ? 1 : rgb_matrix_config.speed)) * abs(led.point.y - 32.0)* sin(r * PI / 128) + (1.5 * (rgb_matrix_config.speed == 0 ? 1 : rgb_matrix_config.speed)) * (led.point.x - (g_tick / 256.0 * 224)) * cos(r * PI / 128) + rgb_matrix_config.hue; 482 hsv.h = (1.5 * (rgb_matrix_config.speed == 0 ? 1 : rgb_matrix_config.speed)) * abs(led.point.y - 32.0)* sin(r * PI / 128) + (1.5 * (rgb_matrix_config.speed == 0 ? 1 : rgb_matrix_config.speed)) * (led.point.x - (g_tick / 256.0 * 224)) * cos(r * PI / 128) + rgb_matrix_config.hue;
465 rgb = hsv_to_rgb( hsv ); 483 rgb = hsv_to_rgb( hsv );
466 rgb_matrix_set_color( i, rgb.r, rgb.g, rgb.b ); 484 rgb_matrix_set_color( i, rgb.r, rgb.g, rgb.b );
@@ -752,16 +770,28 @@ void rgb_matrix_init(void) {
752void rgb_matrix_setup_drivers(void) { 770void rgb_matrix_setup_drivers(void) {
753 // Initialize TWI 771 // Initialize TWI
754 i2c_init(); 772 i2c_init();
755 IS31_init( DRIVER_ADDR_1 ); 773#ifdef IS31FL3731
756 IS31_init( DRIVER_ADDR_2 ); 774 IS31FL3731_init( DRIVER_ADDR_1 );
775 IS31FL3731_init( DRIVER_ADDR_2 );
776#elif defined (IS31FL3733)
777 IS31FL3733_init( DRIVER_ADDR_1 );
778#endif
757 779
758 for ( int index = 0; index < DRIVER_LED_TOTAL; index++ ) { 780 for ( int index = 0; index < DRIVER_LED_TOTAL; index++ ) {
759 bool enabled = true; 781 bool enabled = true;
760 // This only caches it for later 782 // This only caches it for later
761 IS31_set_led_control_register( index, enabled, enabled, enabled ); 783#ifdef IS31FL3731
784 IS31FL3731_set_led_control_register( index, enabled, enabled, enabled );
785#elif defined (IS31FL3733)
786 IS31FL3733_set_led_control_register( index, enabled, enabled, enabled );
787#endif
762 } 788 }
763 // This actually updates the LED drivers 789 // This actually updates the LED drivers
764 IS31_update_led_control_registers( DRIVER_ADDR_1, DRIVER_ADDR_2 ); 790#ifdef IS31FL3731
791 IS31FL3731_update_led_control_registers( DRIVER_ADDR_1, DRIVER_ADDR_2 );
792#elif defined (IS31FL3733)
793 IS31FL3733_update_led_control_registers( DRIVER_ADDR_1, DRIVER_ADDR_2 );
794#endif
765} 795}
766 796
767// Deals with the messy details of incrementing an integer 797// Deals with the messy details of incrementing an integer
@@ -811,11 +841,19 @@ void rgb_matrix_test_led( uint8_t index, bool red, bool green, bool blue ) {
811 { 841 {
812 if ( i == index ) 842 if ( i == index )
813 { 843 {
814 IS31_set_led_control_register( i, red, green, blue ); 844#ifdef IS31FL3731
845 IS31FL3731_set_led_control_register( i, red, green, blue );
846#elif defined (IS31FL3733)
847 IS31FL3733_set_led_control_register( i, red, green, blue );
848#endif
815 } 849 }
816 else 850 else
817 { 851 {
818 IS31_set_led_control_register( i, false, false, false ); 852#ifdef IS31FL3731
853 IS31FL3731_set_led_control_register( i, false, false, false );
854#elif defined (IS31FL3733)
855 IS31FL3733_set_led_control_register( i, false, false, false );
856#endif
819 } 857 }
820 } 858 }
821} 859}
diff --git a/quantum/rgb_matrix.h b/quantum/rgb_matrix.h
index 576931400..b91c9fba5 100644
--- a/quantum/rgb_matrix.h
+++ b/quantum/rgb_matrix.h
@@ -1,5 +1,6 @@
1/* Copyright 2017 Jason Williams 1/* Copyright 2017 Jason Williams
2 * Copyright 2017 Jack Humbert 2 * Copyright 2017 Jack Humbert
3 * Copyright 2018 Yiancar
3 * 4 *
4 * This program is free software: you can redistribute it and/or modify 5 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by 6 * it under the terms of the GNU General Public License as published by
@@ -21,9 +22,14 @@
21#include <stdint.h> 22#include <stdint.h>
22#include <stdbool.h> 23#include <stdbool.h>
23#include "color.h" 24#include "color.h"
24#include "is31fl3731.h"
25#include "quantum.h" 25#include "quantum.h"
26 26
27#ifdef IS31FL3731
28 #include "is31fl3731.h"
29#elif defined (IS31FL3733)
30 #include "is31fl3733.h"
31#endif
32
27typedef struct Point { 33typedef struct Point {
28 uint8_t x; 34 uint8_t x;
29 uint8_t y; 35 uint8_t y;