aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGigahawk <jasperchan515@gmail.com>2021-06-09 18:40:25 -0700
committerGitHub <noreply@github.com>2021-06-10 11:40:25 +1000
commit32b2ac0a807bdb088df685e6118f4c0966b6cca4 (patch)
treec1720e551dc875bd585dc1136f4f99ea00f23c28
parente21a03990116b439de2d4a0181f4a87d048e0366 (diff)
downloadqmk_firmware-32b2ac0a807bdb088df685e6118f4c0966b6cca4.tar.gz
qmk_firmware-32b2ac0a807bdb088df685e6118f4c0966b6cca4.zip
GMMK Pro RGB Support (#13147)
* Enable SPI1 for GMMK pro * Setup initial boilerplate for new LED driver * RGB matrix minimally functional * Map full LED matrix * Return keymap to default * Fix printscreen LED mapping * Reduce max brightness * Default values for AW20216 * Add documentation for AW20216 * Disable console and warnings * Run cformat * Update drivers/awinic/aw20216.h Co-authored-by: Drashna Jaelre <drashna@live.com> * make aw struct match issi struct Co-authored-by: Drashna Jaelre <drashna@live.com> * add led location defines Co-authored-by: Drashna Jaelre <drashna@live.com> * Use led pin definitions in keyboard.c * Add driver indices to led map * Fix elif typo * Run cformat * Update docs * Fix typo in docs * Document global brightness limits Co-authored-by: Drashna Jaelre <drashna@live.com>
-rw-r--r--common_features.mk9
-rw-r--r--docs/feature_rgb_matrix.md68
-rw-r--r--drivers/awinic/aw20216.c166
-rw-r--r--drivers/awinic/aw20216.h251
-rw-r--r--keyboards/gmmk/pro/config.h17
-rw-r--r--keyboards/gmmk/pro/halconf.h7
-rw-r--r--keyboards/gmmk/pro/mcuconf.h6
-rw-r--r--keyboards/gmmk/pro/pro.c222
-rw-r--r--keyboards/gmmk/pro/rules.mk2
-rw-r--r--quantum/rgb_matrix.h2
-rw-r--r--quantum/rgb_matrix_drivers.c16
11 files changed, 765 insertions, 1 deletions
diff --git a/common_features.mk b/common_features.mk
index 1a9fd46b5..37ce928e2 100644
--- a/common_features.mk
+++ b/common_features.mk
@@ -244,7 +244,7 @@ endif
244endif 244endif
245 245
246RGB_MATRIX_ENABLE ?= no 246RGB_MATRIX_ENABLE ?= no
247VALID_RGB_MATRIX_TYPES := IS31FL3731 IS31FL3733 IS31FL3737 IS31FL3741 WS2812 custom 247VALID_RGB_MATRIX_TYPES := AW20216 IS31FL3731 IS31FL3733 IS31FL3737 IS31FL3741 WS2812 custom
248 248
249ifeq ($(strip $(RGB_MATRIX_ENABLE)), yes) 249ifeq ($(strip $(RGB_MATRIX_ENABLE)), yes)
250 ifeq ($(filter $(RGB_MATRIX_DRIVER),$(VALID_RGB_MATRIX_TYPES)),) 250 ifeq ($(filter $(RGB_MATRIX_DRIVER),$(VALID_RGB_MATRIX_TYPES)),)
@@ -261,6 +261,13 @@ endif
261 CIE1931_CURVE := yes 261 CIE1931_CURVE := yes
262 RGB_KEYCODES_ENABLE := yes 262 RGB_KEYCODES_ENABLE := yes
263 263
264 ifeq ($(strip $(RGB_MATRIX_DRIVER)), AW20216)
265 OPT_DEFS += -DAW20216 -DSTM32_SPI -DHAL_USE_SPI=TRUE
266 COMMON_VPATH += $(DRIVER_PATH)/awinic
267 SRC += aw20216.c
268 QUANTUM_LIB_SRC += spi_master.c
269 endif
270
264 ifeq ($(strip $(RGB_MATRIX_DRIVER)), IS31FL3731) 271 ifeq ($(strip $(RGB_MATRIX_DRIVER)), IS31FL3731)
265 OPT_DEFS += -DIS31FL3731 -DSTM32_I2C -DHAL_USE_I2C=TRUE 272 OPT_DEFS += -DIS31FL3731 -DSTM32_I2C -DHAL_USE_I2C=TRUE
266 COMMON_VPATH += $(DRIVER_PATH)/issi 273 COMMON_VPATH += $(DRIVER_PATH)/issi
diff --git a/docs/feature_rgb_matrix.md b/docs/feature_rgb_matrix.md
index 169443fb8..afd72fecf 100644
--- a/docs/feature_rgb_matrix.md
+++ b/docs/feature_rgb_matrix.md
@@ -228,6 +228,74 @@ Configure the hardware via your `config.h`:
228``` 228```
229 229
230--- 230---
231### AW20216 :id=aw20216
232There is basic support for addressable RGB matrix lighting with the SPI AW20216 RGB controller. To enable it, add this to your `rules.mk`:
233
234```makefile
235RGB_MATRIX_ENABLE = yes
236RGB_MATRIX_DRIVER = AW20216
237```
238
239You can use up to 2 AW20216 IC's. Do not specify `DRIVER_<N>_xxx` defines for IC's that are not present on your keyboard. You can define the following items in `config.h`:
240
241| Variable | Description | Default |
242|----------|-------------|---------|
243| `DRIVER_1_CS` | (Required) MCU pin connected to first RGB driver chip select line | B13 |
244| `DRIVER_2_CS` | (Optional) MCU pin connected to second RGB driver chip select line | |
245| `DRIVER_1_EN` | (Required) MCU pin connected to first RGB driver hardware enable line | C13 |
246| `DRIVER_2_EN` | (Optional) MCU pin connected to second RGB driver hardware enable line | |
247| `DRIVER_1_LED_TOTAL` | (Required) How many RGB lights are connected to first RGB driver | |
248| `DRIVER_2_LED_TOTAL` | (Optional) How many RGB lights are connected to second RGB driver | |
249| `DRIVER_COUNT` | (Required) How many RGB driver IC's are present | |
250| `DRIVER_LED_TOTAL` | (Required) How many RGB lights are present across all drivers | |
251| `AW_SCALING_MAX` | (Optional) LED current scaling value (0-255, higher values mean LED is brighter at full PWM) | 150 |
252| `AW_GLOBAL_CURRENT_MAX` | (Optional) Driver global current limit (0-255, higher values means the driver may consume more power) | 150 |
253
254Here is an example using 2 drivers.
255
256```c
257#define DRIVER_1_CS B13
258#define DRIVER_2_CS B14
259// Hardware enable lines may be connected to the same pin
260#define DRIVER_1_EN C13
261#define DRIVER_2_EN C13
262
263#define DRIVER_COUNT 2
264#define DRIVER_1_LED_TOTAL 66
265#define DRIVER_2_LED_TOTAL 32
266#define DRIVER_LED_TOTAL (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)
267```
268
269!> Note the parentheses, this is so when `DRIVER_LED_TOTAL` is used in code and expanded, the values are added together before any additional math is applied to them. As an example, `rand() % (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)` will give very different results than `rand() % DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL`.
270
271Define these arrays listing all the LEDs in your `<keyboard>.c`:
272
273```c
274const aw_led g_aw_leds[DRIVER_LED_TOTAL] = {
275/* Each AW20216 channel is controlled by a register at some offset between 0x00
276 * and 0xD7 inclusive.
277 * See drivers/awinic/aw20216.h for the mapping between register offsets and
278 * driver pin locations.
279 * driver
280 * | R location
281 * | | G location
282 * | | | B location
283 * | | | | */
284 { 0, CS1_SW1, CS2_SW1, CS3_SW1 },
285 { 0, CS4_SW1, CS5_SW1, CS6_SW1 },
286 { 0, CS7_SW1, CS8_SW1, CS9_SW1 },
287 { 0, CS10_SW1, CS11_SW1, CS12_SW1 },
288 { 0, CS13_SW1, CS14_SW1, CS15_SW1 },
289 ...
290 { 1, CS1_SW1, CS2_SW1, CS3_SW1 },
291 { 1, CS13_SW1, CS14_SW1, CS15_SW1 },
292 { 1, CS16_SW1, CS17_SW1, CS18_SW1 },
293 { 1, CS4_SW2, CS5_SW2, CS6_SW2 },
294 ...
295};
296```
297
298---
231 299
232From this point forward the configuration is the same for all the drivers. The `led_config_t` struct provides a key electrical matrix to led index lookup table, what the physical position of each LED is on the board, and what type of key or usage the LED if the LED represents. Here is a brief example: 300From this point forward the configuration is the same for all the drivers. The `led_config_t` struct provides a key electrical matrix to led index lookup table, what the physical position of each LED is on the board, and what type of key or usage the LED if the LED represents. Here is a brief example:
233 301
diff --git a/drivers/awinic/aw20216.c b/drivers/awinic/aw20216.c
new file mode 100644
index 000000000..236c42a3c
--- /dev/null
+++ b/drivers/awinic/aw20216.c
@@ -0,0 +1,166 @@
1/* Copyright 2021 Jasper Chan
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include "aw20216.h"
18#include "spi_master.h"
19
20/* The AW20216 appears to be somewhat similar to the IS31FL743, although quite
21 * a few things are different, such as the command byte format and page ordering.
22 * The LED addresses start from 0x00 instead of 0x01.
23 */
24#define AWINIC_ID 0b1010 << 4
25
26#define AW_PAGE_FUNCTION 0x00 << 1 // PG0, Function registers
27#define AW_PAGE_PWM 0x01 << 1 // PG1, LED PWM control
28#define AW_PAGE_SCALING 0x02 << 1 // PG2, LED current scaling control
29#define AW_PAGE_PATCHOICE 0x03 << 1 // PG3, Pattern choice?
30#define AW_PAGE_PWMSCALING 0x04 << 1 // PG4, LED PWM + Scaling control?
31
32#define AW_WRITE 0
33#define AW_READ 1
34
35#define AW_REG_CONFIGURATION 0x00 // PG0
36#define AW_REG_GLOBALCURRENT 0x01 // PG0
37
38// Default value of AW_REG_CONFIGURATION
39// D7:D4 = 1011, SWSEL (SW1~SW12 active)
40// D3 = 0?, reserved (apparently this should be 1 but it doesn't seem to matter)
41// D2:D1 = 00, OSDE (open/short detection enable)
42// D0 = 0, CHIPEN (write 1 to enable LEDs when hardware enable pulled high)
43#define AW_CONFIG_DEFAULT 0b10110000
44#define AW_CHIPEN 1
45
46#ifndef AW_SCALING_MAX
47# define AW_SCALING_MAX 150
48#endif
49
50#ifndef AW_GLOBAL_CURRENT_MAX
51# define AW_GLOBAL_CURRENT_MAX 150
52#endif
53
54#ifndef DRIVER_1_CS
55# define DRIVER_1_CS B13
56#endif
57
58#ifndef DRIVER_1_EN
59# define DRIVER_1_EN C13
60#endif
61
62uint8_t g_spi_transfer_buffer[20] = {0};
63aw_led g_pwm_buffer[DRIVER_LED_TOTAL];
64bool g_pwm_buffer_update_required[DRIVER_LED_TOTAL];
65
66bool AW20216_write_register(pin_t slave_pin, uint8_t page, uint8_t reg, uint8_t data) {
67 // Do we need to call spi_stop() if this fails?
68 if (!spi_start(slave_pin, false, 0, 16)) {
69 return false;
70 }
71
72 g_spi_transfer_buffer[0] = (AWINIC_ID | page | AW_WRITE);
73 g_spi_transfer_buffer[1] = reg;
74 g_spi_transfer_buffer[2] = data;
75
76 if (spi_transmit(g_spi_transfer_buffer, 3) != SPI_STATUS_SUCCESS) {
77 spi_stop();
78 return false;
79 }
80 spi_stop();
81 return true;
82}
83
84bool AW20216_init_scaling(void) {
85 // Set constant current to the max, control brightness with PWM
86 aw_led led;
87 for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) {
88 led = g_aw_leds[i];
89 if (led.driver == 0) {
90 AW20216_write_register(DRIVER_1_CS, AW_PAGE_SCALING, led.r, AW_SCALING_MAX);
91 AW20216_write_register(DRIVER_1_CS, AW_PAGE_SCALING, led.g, AW_SCALING_MAX);
92 AW20216_write_register(DRIVER_1_CS, AW_PAGE_SCALING, led.b, AW_SCALING_MAX);
93 }
94#ifdef DRIVER_2_CS
95 else if (led.driver == 1) {
96 AW20216_write_register(DRIVER_2_CS, AW_PAGE_SCALING, led.r, AW_SCALING_MAX);
97 AW20216_write_register(DRIVER_2_CS, AW_PAGE_SCALING, led.g, AW_SCALING_MAX);
98 AW20216_write_register(DRIVER_2_CS, AW_PAGE_SCALING, led.b, AW_SCALING_MAX);
99 }
100#endif
101 }
102 return true;
103}
104
105bool AW20216_soft_enable(void) {
106 AW20216_write_register(DRIVER_1_CS, AW_PAGE_FUNCTION, AW_REG_CONFIGURATION, AW_CONFIG_DEFAULT | AW_CHIPEN);
107#ifdef DRIVER_2_CS
108 AW20216_write_register(DRIVER_2_CS, AW_PAGE_FUNCTION, AW_REG_CONFIGURATION, AW_CONFIG_DEFAULT | AW_CHIPEN);
109#endif
110 return true;
111}
112
113void AW20216_update_pwm(int index, uint8_t red, uint8_t green, uint8_t blue) {
114 aw_led led = g_aw_leds[index];
115 if (led.driver == 0) {
116 AW20216_write_register(DRIVER_1_CS, AW_PAGE_PWM, led.r, red);
117 AW20216_write_register(DRIVER_1_CS, AW_PAGE_PWM, led.g, green);
118 AW20216_write_register(DRIVER_1_CS, AW_PAGE_PWM, led.b, blue);
119 }
120#ifdef DRIVER_2_CS
121 else if (led.driver == 1) {
122 AW20216_write_register(DRIVER_2_CS, AW_PAGE_PWM, led.r, red);
123 AW20216_write_register(DRIVER_2_CS, AW_PAGE_PWM, led.g, green);
124 AW20216_write_register(DRIVER_2_CS, AW_PAGE_PWM, led.b, blue);
125 }
126#endif
127 return;
128}
129
130void AW20216_init(void) {
131 // All LEDs should start with all scaling and PWM registers as off
132 setPinOutput(DRIVER_1_EN);
133 writePinHigh(DRIVER_1_EN);
134 AW20216_write_register(DRIVER_1_CS, AW_PAGE_FUNCTION, AW_REG_GLOBALCURRENT, AW_GLOBAL_CURRENT_MAX);
135#ifdef DRIVER_2_EN
136 setPinOutput(DRIVER_2_EN);
137 writePinHigh(DRIVER_2_EN);
138 AW20216_write_register(DRIVER_2_CS, AW_PAGE_FUNCTION, AW_REG_GLOBALCURRENT, AW_GLOBAL_CURRENT_MAX);
139#endif
140 AW20216_init_scaling();
141 AW20216_soft_enable();
142 return;
143}
144
145void AW20216_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) {
146 g_pwm_buffer[index].r = red;
147 g_pwm_buffer[index].g = green;
148 g_pwm_buffer[index].b = blue;
149 g_pwm_buffer_update_required[index] = true;
150 return;
151}
152void AW20216_set_color_all(uint8_t red, uint8_t green, uint8_t blue) {
153 for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) {
154 AW20216_set_color(i, red, green, blue);
155 }
156 return;
157}
158void AW20216_update_pwm_buffers(void) {
159 for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) {
160 if (g_pwm_buffer_update_required[i]) {
161 AW20216_update_pwm(i, g_pwm_buffer[i].r, g_pwm_buffer[i].g, g_pwm_buffer[i].b);
162 g_pwm_buffer_update_required[i] = false;
163 }
164 }
165 return;
166}
diff --git a/drivers/awinic/aw20216.h b/drivers/awinic/aw20216.h
new file mode 100644
index 000000000..9c6865cc8
--- /dev/null
+++ b/drivers/awinic/aw20216.h
@@ -0,0 +1,251 @@
1/* Copyright 2021 Jasper Chan (Gigahawk)
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#pragma once
18
19#include <stdint.h>
20#include <stdbool.h>
21
22typedef struct aw_led {
23 uint8_t driver : 2;
24 uint8_t r;
25 uint8_t g;
26 uint8_t b;
27} aw_led;
28
29extern const aw_led g_aw_leds[DRIVER_LED_TOTAL];
30
31void AW20216_init(void);
32void AW20216_set_color(int index, uint8_t red, uint8_t green, uint8_t blue);
33void AW20216_set_color_all(uint8_t red, uint8_t green, uint8_t blue);
34void AW20216_update_pwm_buffers(void);
35
36#define CS1_SW1 0x00
37#define CS2_SW1 0x01
38#define CS3_SW1 0x02
39#define CS4_SW1 0x03
40#define CS5_SW1 0x04
41#define CS6_SW1 0x05
42#define CS7_SW1 0x06
43#define CS8_SW1 0x07
44#define CS9_SW1 0x08
45#define CS10_SW1 0x09
46#define CS11_SW1 0x0A
47#define CS12_SW1 0x0B
48#define CS13_SW1 0x0C
49#define CS14_SW1 0x0D
50#define CS15_SW1 0x0E
51#define CS16_SW1 0x0F
52#define CS17_SW1 0x10
53#define CS18_SW1 0x11
54#define CS1_SW2 0x12
55#define CS2_SW2 0x13
56#define CS3_SW2 0x14
57#define CS4_SW2 0x15
58#define CS5_SW2 0x16
59#define CS6_SW2 0x17
60#define CS7_SW2 0x18
61#define CS8_SW2 0x19
62#define CS9_SW2 0x1A
63#define CS10_SW2 0x1B
64#define CS11_SW2 0x1C
65#define CS12_SW2 0x1D
66#define CS13_SW2 0x1E
67#define CS14_SW2 0x1F
68#define CS15_SW2 0x20
69#define CS16_SW2 0x21
70#define CS17_SW2 0x22
71#define CS18_SW2 0x23
72#define CS1_SW3 0x24
73#define CS2_SW3 0x25
74#define CS3_SW3 0x26
75#define CS4_SW3 0x27
76#define CS5_SW3 0x28
77#define CS6_SW3 0x29
78#define CS7_SW3 0x2A
79#define CS8_SW3 0x2B
80#define CS9_SW3 0x2C
81#define CS10_SW3 0x2D
82#define CS11_SW3 0x2E
83#define CS12_SW3 0x2F
84#define CS13_SW3 0x30
85#define CS14_SW3 0x31
86#define CS15_SW3 0x32
87#define CS16_SW3 0x33
88#define CS17_SW3 0x34
89#define CS18_SW3 0x35
90#define CS1_SW4 0x36
91#define CS2_SW4 0x37
92#define CS3_SW4 0x38
93#define CS4_SW4 0x39
94#define CS5_SW4 0x3A
95#define CS6_SW4 0x3B
96#define CS7_SW4 0x3C
97#define CS8_SW4 0x3D
98#define CS9_SW4 0x3E
99#define CS10_SW4 0x3F
100#define CS11_SW4 0x40
101#define CS12_SW4 0x41
102#define CS13_SW4 0x42
103#define CS14_SW4 0x43
104#define CS15_SW4 0x44
105#define CS16_SW4 0x45
106#define CS17_SW4 0x46
107#define CS18_SW4 0x47
108#define CS1_SW5 0x48
109#define CS2_SW5 0x49
110#define CS3_SW5 0x4A
111#define CS4_SW5 0x4B
112#define CS5_SW5 0x4C
113#define CS6_SW5 0x4D
114#define CS7_SW5 0x4E
115#define CS8_SW5 0x4F
116#define CS9_SW5 0x50
117#define CS10_SW5 0x51
118#define CS11_SW5 0x52
119#define CS12_SW5 0x53
120#define CS13_SW5 0x54
121#define CS14_SW5 0x55
122#define CS15_SW5 0x56
123#define CS16_SW5 0x57
124#define CS17_SW5 0x58
125#define CS18_SW5 0x59
126#define CS1_SW6 0x5A
127#define CS2_SW6 0x5B
128#define CS3_SW6 0x5C
129#define CS4_SW6 0x5D
130#define CS5_SW6 0x5E
131#define CS6_SW6 0x5F
132#define CS7_SW6 0x60
133#define CS8_SW6 0x61
134#define CS9_SW6 0x62
135#define CS10_SW6 0x63
136#define CS11_SW6 0x64
137#define CS12_SW6 0x65
138#define CS13_SW6 0x66
139#define CS14_SW6 0x67
140#define CS15_SW6 0x68
141#define CS16_SW6 0x69
142#define CS17_SW6 0x6A
143#define CS18_SW6 0x6B
144#define CS1_SW7 0x6C
145#define CS2_SW7 0x6D
146#define CS3_SW7 0x6E
147#define CS4_SW7 0x6F
148#define CS5_SW7 0x70
149#define CS6_SW7 0x71
150#define CS7_SW7 0x72
151#define CS8_SW7 0x73
152#define CS9_SW7 0x74
153#define CS10_SW7 0x75
154#define CS11_SW7 0x76
155#define CS12_SW7 0x77
156#define CS13_SW7 0x78
157#define CS14_SW7 0x79
158#define CS15_SW7 0x7A
159#define CS16_SW7 0x7B
160#define CS17_SW7 0x7C
161#define CS18_SW7 0x7D
162#define CS1_SW8 0x7E
163#define CS2_SW8 0x7F
164#define CS3_SW8 0x80
165#define CS4_SW8 0x81
166#define CS5_SW8 0x82
167#define CS6_SW8 0x83
168#define CS7_SW8 0x84
169#define CS8_SW8 0x85
170#define CS9_SW8 0x86
171#define CS10_SW8 0x87
172#define CS11_SW8 0x88
173#define CS12_SW8 0x89
174#define CS13_SW8 0x8A
175#define CS14_SW8 0x8B
176#define CS15_SW8 0x8C
177#define CS16_SW8 0x8D
178#define CS17_SW8 0x8E
179#define CS18_SW8 0x8F
180#define CS1_SW9 0x90
181#define CS2_SW9 0x91
182#define CS3_SW9 0x92
183#define CS4_SW9 0x93
184#define CS5_SW9 0x94
185#define CS6_SW9 0x95
186#define CS7_SW9 0x96
187#define CS8_SW9 0x97
188#define CS9_SW9 0x98
189#define CS10_SW9 0x99
190#define CS11_SW9 0x9A
191#define CS12_SW9 0x9B
192#define CS13_SW9 0x9C
193#define CS14_SW9 0x9D
194#define CS15_SW9 0x9E
195#define CS16_SW9 0x9F
196#define CS17_SW9 0xA0
197#define CS18_SW9 0xA1
198#define CS1_SW10 0xA2
199#define CS2_SW10 0xA3
200#define CS3_SW10 0xA4
201#define CS4_SW10 0xA5
202#define CS5_SW10 0xA6
203#define CS6_SW10 0xA7
204#define CS7_SW10 0xA8
205#define CS8_SW10 0xA9
206#define CS9_SW10 0xAA
207#define CS10_SW10 0xAB
208#define CS11_SW10 0xAC
209#define CS12_SW10 0xAD
210#define CS13_SW10 0xAE
211#define CS14_SW10 0xAF
212#define CS15_SW10 0xB0
213#define CS16_SW10 0xB1
214#define CS17_SW10 0xB2
215#define CS18_SW10 0xB3
216#define CS1_SW11 0xB4
217#define CS2_SW11 0xB5
218#define CS3_SW11 0xB6
219#define CS4_SW11 0xB7
220#define CS5_SW11 0xB8
221#define CS6_SW11 0xB9
222#define CS7_SW11 0xBA
223#define CS8_SW11 0xBB
224#define CS9_SW11 0xBC
225#define CS10_SW11 0xBD
226#define CS11_SW11 0xBE
227#define CS12_SW11 0xBF
228#define CS13_SW11 0xC0
229#define CS14_SW11 0xC1
230#define CS15_SW11 0xC2
231#define CS16_SW11 0xC3
232#define CS17_SW11 0xC4
233#define CS18_SW11 0xC5
234#define CS1_SW12 0xC6
235#define CS2_SW12 0xC7
236#define CS3_SW12 0xC8
237#define CS4_SW12 0xC9
238#define CS5_SW12 0xCA
239#define CS6_SW12 0xCB
240#define CS7_SW12 0xCC
241#define CS8_SW12 0xCD
242#define CS9_SW12 0xCE
243#define CS10_SW12 0xCF
244#define CS11_SW12 0xD0
245#define CS12_SW12 0xD1
246#define CS13_SW12 0xD2
247#define CS14_SW12 0xD3
248#define CS15_SW12 0xD4
249#define CS16_SW12 0xD5
250#define CS17_SW12 0xD6
251#define CS18_SW12 0xD7
diff --git a/keyboards/gmmk/pro/config.h b/keyboards/gmmk/pro/config.h
index ab3c7a7a2..64062bece 100644
--- a/keyboards/gmmk/pro/config.h
+++ b/keyboards/gmmk/pro/config.h
@@ -46,3 +46,20 @@
46#define LOCKING_SUPPORT_ENABLE 46#define LOCKING_SUPPORT_ENABLE
47/* Locking resynchronize hack */ 47/* Locking resynchronize hack */
48#define LOCKING_RESYNC_ENABLE 48#define LOCKING_RESYNC_ENABLE
49
50/* SPI Config for LED Driver */
51#define SPI_DRIVER SPID1
52#define SPI_SCK_PIN A5
53#define SPI_MOSI_PIN A6
54#define SPI_MISO_PIN A7
55
56#define DRIVER_1_CS B13
57#define DRIVER_2_CS B14
58#define DRIVER_1_EN C13
59#define DRIVER_2_EN C13
60
61#define DRIVER_COUNT 2
62#define DRIVER_1_LED_TOTAL 66
63#define DRIVER_2_LED_TOTAL 32
64#define DRIVER_LED_TOTAL (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)
65
diff --git a/keyboards/gmmk/pro/halconf.h b/keyboards/gmmk/pro/halconf.h
new file mode 100644
index 000000000..23ecb202a
--- /dev/null
+++ b/keyboards/gmmk/pro/halconf.h
@@ -0,0 +1,7 @@
1#pragma once
2
3#define HAL_USE_SPI TRUE
4#define SPI_USE_WAIT TRUE
5#define SPI_SELECT_MODE SPI_SELECT_MODE_PAD
6
7#include_next <halconf.h>
diff --git a/keyboards/gmmk/pro/mcuconf.h b/keyboards/gmmk/pro/mcuconf.h
new file mode 100644
index 000000000..bb1c0acde
--- /dev/null
+++ b/keyboards/gmmk/pro/mcuconf.h
@@ -0,0 +1,6 @@
1#pragma once
2
3#include_next <mcuconf.h>
4
5#undef STM32_SPI_USE_SPI1
6#define STM32_SPI_USE_SPI1 TRUE
diff --git a/keyboards/gmmk/pro/pro.c b/keyboards/gmmk/pro/pro.c
index 816d089a5..3a343f223 100644
--- a/keyboards/gmmk/pro/pro.c
+++ b/keyboards/gmmk/pro/pro.c
@@ -14,3 +14,225 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 15 */
16#include "pro.h" 16#include "pro.h"
17
18#ifdef RGB_MATRIX_ENABLE
19led_config_t g_led_config = { {
20 { 4, NO_LED, NO_LED, 97, 65, 79, 5, 28 },
21 { 8, 2, 9, 0, 10, 75, 1, 7 },
22 { 14, 3, 15, NO_LED, 16, 86, 6, 13 },
23 { 20, 18, 21, 23, 22, 94, 12, 19 },
24 { 25, 30, 26, 31, 27, 32, 29, 24 },
25 { 41, 36, 42, 37, 43, 38, 35, 40 },
26 { 46, 89, 47, 34, 48, 72, 78, 45 },
27 { 52, 39, 53, 101, 54, 82, 44, 51 },
28 { 58, 63, 59, 64, NO_LED, 60, 62, 57 },
29 { 11, 90, 55, 17, 33, 49, NO_LED, 69 },
30 { NO_LED, 85, 93, 61, 100, 66, 50, 56 }
31}, {
32 { 0, 0 }, // 0, ESC, k13
33 { 0, 15 }, // 1, ~, k16
34 { 4, 26 }, // 2, Tab, k11
35 { 5, 38 }, // 3, Caps, k21
36 { 9, 49 }, // 4, Sh_L, k00
37 { 2, 61 }, // 5, Ct_L, k06
38 { 18, 0 }, // 6, F1, k26
39 { 14, 15 }, // 7, 1, k17
40 { 22, 26 }, // 8, Q, k10
41 { 25, 38 }, // 9, A, k12
42 { 33, 49 }, // 10, Z, k14
43 { 20, 61 }, // 11, Win_L, k90
44 { 33, 0 }, // 12, F2, k36
45 { 29, 15 }, // 13, 2, k27
46 { 36, 26 }, // 14, W, k20
47 { 40, 38 }, // 15, S, k22
48 { 47, 49 }, // 16, X, k24
49 { 38, 61 }, // 17, Alt_L, k93
50 { 47, 0 }, // 18, F3, k31
51 { 43, 15 }, // 19, 3, k37
52 { 51, 26 }, // 20, E, k30
53 { 54, 38 }, // 21, D, k32
54 { 61, 49 }, // 22, C, k34
55 { 61, 0 }, // 23, F4, k33
56 { 58, 15 }, // 24, 4, k47
57 { 65, 26 }, // 25, R, k40
58 { 69, 38 }, // 26, F, k42
59 { 76, 49 }, // 27, V, k44
60 { 79, 0 }, // 28, F5, k07
61 { 72, 15 }, // 29, 5, k46
62 { 79, 26 }, // 30, T, k41
63 { 83, 38 }, // 31, G, k43
64 { 90, 49 }, // 32, B, k45
65 { 92, 61 }, // 33, SPACE, k94
66 { 94, 0 }, // 34, F6, k63
67 { 87, 15 }, // 35, 6, k56
68 { 94, 26 }, // 36, Y, k51
69 { 98, 38 }, // 37, H, k53
70 { 105, 49 }, // 38, N, k55
71 { 108, 0 }, // 39, F7, k71
72 { 101, 15 }, // 40, 7, k57
73 { 108, 26 }, // 41, U, k50
74 { 112, 38 }, // 42, J, k52
75 { 119, 49 }, // 43, M, k54
76 { 123, 0 }, // 44, F8, k76
77 { 116, 15 }, // 45, 8, k67
78 { 123, 26 }, // 46, I, k60
79 { 126, 38 }, // 47, K, k62
80 { 134, 49 }, // 48, ,, k64
81 { 145, 61 }, // 49, Alt_R, k95
82 { 141, 0 }, // 50, F9, ka6
83 { 130, 15 }, // 51, 9, k77
84 { 137, 26 }, // 52, O, k70
85 { 141, 38 }, // 53, L, k72
86 { 148, 49 }, // 54, ., k74
87 { 159, 61 }, // 55, FN, k92
88 { 155, 0 }, // 56, F10, ka7
89 { 145, 15 }, // 57, 0, k87
90 { 152, 26 }, // 58, P, k80
91 { 155, 38 }, // 59, ;, k82
92 { 163, 49 }, // 60, ?, k85
93 { 170, 0 }, // 61, F11, ka3
94 { 159, 15 }, // 62, -, k86
95 { 166, 26 }, // 63, [, k81
96 { 170, 38 }, // 64, ", k83
97 { 173, 61 }, // 65, Ct_R, k04
98 { 184, 0 }, // 66, F12, ka5
99 { 0, 8 }, // 67, LED, l01
100 { 224, 8 }, // 68, LED, l11
101 { 202, 0 }, // 69, Prt, k97
102 { 0, 15 }, // 70, LED, l02
103 { 224, 15 }, // 71, LED, l12
104 { 224, 15 }, // 72, Del, k65
105 { 0, 21 }, // 73, LED, l03
106 { 224, 21 }, // 74, LED, l13
107 { 224, 26 }, // 75, PgUp, k15
108 { 0, 28 }, // 76, LED, l04
109 { 224, 28 }, // 77, LED, l14
110 { 173, 15 }, // 78, =, k66
111 { 220, 64 }, // 79, Right, k05
112 { 0, 35 }, // 80, LED, l05
113 { 224, 35 }, // 81, LED, l15
114 { 224, 49 }, // 82, End, k75
115 { 0, 42 }, // 83, LED, l06
116 { 224, 42 }, // 84, LED, l16
117 { 195, 15 }, // 85, BSpc, ka1
118 { 224, 38 }, // 86, PgDn, k25
119 { 0, 48 }, // 87, LED, l07
120 { 224, 48 }, // 88, LED, l17
121 { 181, 26 }, // 89, ], k61
122 { 182, 49 }, // 90, Sh_R, k91
123 { 0, 55 }, // 91, LED, l08
124 { 224, 55 }, // 92, LED, l18
125 { 199, 26 }, // 93, \, ka2
126 { 206, 52 }, // 94, Up, k35
127 { 191, 64 }, // 95, Left, k03
128 { 193, 38 }, // 96, Enter, ka4
129 { 206, 64 } // 97, Down, k73
130}, {
131 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
132 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
133 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 4, 2, 2, 4, 2, 2,
134 4, 2, 2, 4, 4, 2, 2, 4, 2, 2, 4, 4, 2, 2, 4, 4, 2, 2, 4, 4, 4, 4, 4
135} };
136
137const aw_led g_aw_leds[DRIVER_LED_TOTAL] = {
138 { 0, CS1_SW1, CS2_SW1, CS3_SW1 }, // 0, ESC, k13
139 { 0, CS4_SW1, CS5_SW1, CS6_SW1 }, // 1, ~, k16
140 { 0, CS7_SW1, CS8_SW1, CS9_SW1 }, // 2, Tab, k11
141 { 0, CS10_SW1, CS11_SW1, CS12_SW1 }, // 3, Caps, k21
142 { 0, CS13_SW1, CS14_SW1, CS15_SW1 }, // 4, Sh_L, k00
143 { 0, CS16_SW1, CS17_SW1, CS18_SW1 }, // 5, Ct_L, k06
144 { 0, CS1_SW2, CS2_SW2, CS3_SW2 }, // 6, F1, k26
145 { 0, CS4_SW2, CS5_SW2, CS6_SW2 }, // 7, 1, k17
146 { 0, CS7_SW2, CS8_SW2, CS9_SW2 }, // 8, Q, k10
147 { 0, CS10_SW2, CS11_SW2, CS12_SW2 }, // 9, A, k12
148 { 0, CS13_SW2, CS14_SW2, CS15_SW2 }, // 10, Z, k14
149 { 0, CS16_SW2, CS17_SW2, CS18_SW2 }, // 11, Win_L, k90
150 { 0, CS1_SW3, CS2_SW3, CS3_SW3 }, // 12, F2, k36
151 { 0, CS4_SW3, CS5_SW3, CS6_SW3 }, // 13, 2, k27
152 { 0, CS7_SW3, CS8_SW3, CS9_SW3 }, // 14, W, k20
153 { 0, CS10_SW3, CS11_SW3, CS12_SW3 }, // 15, S, k22
154 { 0, CS13_SW3, CS14_SW3, CS15_SW3 }, // 16, X, k24
155 { 0, CS16_SW3, CS17_SW3, CS18_SW3 }, // 17, Alt_L, k93
156 { 0, CS1_SW4, CS2_SW4, CS3_SW4 }, // 18, F3, k31
157 { 0, CS4_SW4, CS5_SW4, CS6_SW4 }, // 19, 3, k37
158 { 0, CS7_SW4, CS8_SW4, CS9_SW4 }, // 20, E, k30
159 { 0, CS10_SW4, CS11_SW4, CS12_SW4 }, // 21, D, k32
160 { 0, CS13_SW4, CS14_SW4, CS15_SW4 }, // 22, C, k34
161 { 0, CS1_SW5, CS2_SW5, CS3_SW5 }, // 23, F4, k33
162 { 0, CS4_SW5, CS5_SW5, CS6_SW5 }, // 24, 4, k47
163 { 0, CS7_SW5, CS8_SW5, CS9_SW5 }, // 25, R, k40
164 { 0, CS10_SW5, CS11_SW5, CS12_SW5 }, // 26, F, k42
165 { 0, CS13_SW5, CS14_SW5, CS15_SW5 }, // 27, V, k44
166 { 0, CS1_SW6, CS2_SW6, CS3_SW6 }, // 28, F5, k07
167 { 0, CS4_SW6, CS5_SW6, CS6_SW6 }, // 29, 5, k46
168 { 0, CS7_SW6, CS8_SW6, CS9_SW6 }, // 30, T, k41
169 { 0, CS10_SW6, CS11_SW6, CS12_SW6 }, // 31, G, k43
170 { 0, CS13_SW6, CS14_SW6, CS15_SW6 }, // 32, B, k45
171 { 0, CS16_SW6, CS17_SW6, CS18_SW6 }, // 33, SPACE, k94
172 { 0, CS1_SW7, CS2_SW7, CS3_SW7 }, // 34, F6, k63
173 { 0, CS4_SW7, CS5_SW7, CS6_SW7 }, // 35, 6, k56
174 { 0, CS7_SW7, CS8_SW7, CS9_SW7 }, // 36, Y, k51
175 { 0, CS10_SW7, CS11_SW7, CS12_SW7 }, // 37, H, k53
176 { 0, CS13_SW7, CS14_SW7, CS15_SW7 }, // 38, N, k55
177 { 0, CS1_SW8, CS2_SW8, CS3_SW8 }, // 39, F7, k71
178 { 0, CS4_SW8, CS5_SW8, CS6_SW8 }, // 40, 7, k57
179 { 0, CS7_SW8, CS8_SW8, CS9_SW8 }, // 41, U, k50
180 { 0, CS10_SW8, CS11_SW8, CS12_SW8 }, // 42, J, k52
181 { 0, CS13_SW8, CS14_SW8, CS15_SW8 }, // 43, M, k54
182 { 0, CS1_SW9, CS2_SW9, CS3_SW9 }, // 44, F8, k76
183 { 0, CS4_SW9, CS5_SW9, CS6_SW9 }, // 45, 8, k67
184 { 0, CS7_SW9, CS8_SW9, CS9_SW9 }, // 46, I, k60
185 { 0, CS10_SW9, CS11_SW9, CS12_SW9 }, // 47, K, k62
186 { 0, CS13_SW9, CS14_SW9, CS15_SW9 }, // 48, ,, k64
187 { 0, CS16_SW9, CS17_SW9, CS18_SW9 }, // 49, Alt_R, k95
188 { 0, CS1_SW10, CS2_SW10, CS3_SW10 }, // 50, F9, ka6
189 { 0, CS4_SW10, CS5_SW10, CS6_SW10 }, // 51, 9, k77
190 { 0, CS7_SW10, CS8_SW10, CS9_SW10 }, // 52, O, k70
191 { 0, CS10_SW10, CS11_SW10, CS12_SW10 }, // 53, L, k72
192 { 0, CS13_SW10, CS14_SW10, CS15_SW10 }, // 54, ., k74
193 { 0, CS16_SW10, CS17_SW10, CS18_SW10 }, // 55, FN, k92
194 { 0, CS1_SW11, CS2_SW11, CS3_SW11 }, // 56, F10, ka7
195 { 0, CS4_SW11, CS5_SW11, CS6_SW11 }, // 57, 0, k87
196 { 0, CS7_SW11, CS8_SW11, CS9_SW11 }, // 58, P, k80
197 { 0, CS10_SW11, CS11_SW11, CS12_SW11 }, // 59, ;, k82
198 { 0, CS13_SW11, CS14_SW11, CS15_SW11 }, // 60, ?, k85
199 { 0, CS1_SW12, CS2_SW12, CS3_SW12 }, // 61, F11, ka3
200 { 0, CS4_SW12, CS5_SW12, CS6_SW12 }, // 62, -, k86
201 { 0, CS7_SW12, CS8_SW12, CS9_SW12 }, // 63, [, k81
202 { 0, CS10_SW12, CS11_SW12, CS12_SW12 }, // 64, ", k83
203 { 0, CS16_SW12, CS17_SW12, CS18_SW12 }, // 65, Ct_R, k04
204
205 { 1, CS1_SW1, CS2_SW1, CS3_SW1 }, // 66, F12, ka5
206 { 1, CS13_SW1, CS14_SW1, CS15_SW1 }, // 67, LED, l01
207 { 1, CS16_SW1, CS17_SW1, CS18_SW1 }, // 68, LED, l11
208 { 1, CS4_SW2, CS5_SW2, CS6_SW2 }, // 69, Prt, k97
209 { 1, CS13_SW2, CS14_SW2, CS15_SW2 }, // 70, LED, l02
210 { 1, CS16_SW2, CS17_SW2, CS18_SW2 }, // 71, LED, l12
211 { 1, CS4_SW3, CS5_SW3, CS6_SW3 }, // 72, Del, k65
212 { 1, CS13_SW3, CS14_SW3, CS15_SW3 }, // 73, LED, l03
213 { 1, CS16_SW3, CS17_SW3, CS18_SW3 }, // 74, LED, l13
214 { 1, CS4_SW4, CS5_SW4, CS6_SW4 }, // 75, PgUp, k15
215 { 1, CS13_SW4, CS14_SW4, CS15_SW4 }, // 76, LED, l04
216 { 1, CS16_SW4, CS17_SW4, CS18_SW4 }, // 77, LED, l14
217 { 1, CS1_SW5, CS2_SW5, CS3_SW5 }, // 78, =, k66
218 { 1, CS10_SW5, CS11_SW5, CS12_SW5 }, // 79, Right, k05
219 { 1, CS13_SW5, CS14_SW5, CS15_SW5 }, // 80, LED, l05
220 { 1, CS16_SW5, CS17_SW5, CS18_SW5 }, // 81, LED, l15
221 { 1, CS4_SW6, CS5_SW6, CS6_SW6 }, // 82, End, k75
222 { 1, CS13_SW6, CS14_SW6, CS15_SW6 }, // 83, LED, l06
223 { 1, CS16_SW6, CS17_SW6, CS18_SW6 }, // 84, LED, l16
224 { 1, CS1_SW7, CS2_SW7, CS3_SW7 }, // 85, BSpc, ka1
225 { 1, CS4_SW7, CS5_SW7, CS6_SW7 }, // 86, PgDn, k25
226 { 1, CS13_SW7, CS14_SW7, CS15_SW7 }, // 87, LED, l07
227 { 1, CS16_SW7, CS17_SW7, CS18_SW7 }, // 88, LED, l17
228 { 1, CS1_SW8, CS2_SW8, CS3_SW8 }, // 89, ], k61
229 { 1, CS4_SW8, CS5_SW8, CS6_SW8 }, // 90, Sh_R, k91
230 { 1, CS13_SW8, CS14_SW8, CS15_SW8 }, // 91, LED, l08
231 { 1, CS16_SW8, CS17_SW8, CS18_SW8 }, // 92, LED, l18
232 { 1, CS1_SW9, CS2_SW9, CS3_SW9 }, // 93, \, ka2
233 { 1, CS4_SW9, CS5_SW9, CS6_SW9 }, // 94, Up, k35
234 { 1, CS4_SW10, CS5_SW10, CS6_SW10 }, // 95, Left, k03
235 { 1, CS1_SW11, CS2_SW11, CS3_SW11 }, // 96, Enter, ka4
236 { 1, CS4_SW11, CS5_SW11, CS6_SW11 }, // 97, Down, k73
237};
238#endif
diff --git a/keyboards/gmmk/pro/rules.mk b/keyboards/gmmk/pro/rules.mk
index b12d055a3..6221d6408 100644
--- a/keyboards/gmmk/pro/rules.mk
+++ b/keyboards/gmmk/pro/rules.mk
@@ -21,3 +21,5 @@ RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow
21BLUETOOTH_ENABLE = no # Enable Bluetooth 21BLUETOOTH_ENABLE = no # Enable Bluetooth
22AUDIO_ENABLE = no # Audio output 22AUDIO_ENABLE = no # Audio output
23ENCODER_ENABLE = yes 23ENCODER_ENABLE = yes
24RGB_MATRIX_ENABLE = yes
25RGB_MATRIX_DRIVER = AW20216
diff --git a/quantum/rgb_matrix.h b/quantum/rgb_matrix.h
index a615b8422..741a2fe44 100644
--- a/quantum/rgb_matrix.h
+++ b/quantum/rgb_matrix.h
@@ -33,6 +33,8 @@
33# include "is31fl3737.h" 33# include "is31fl3737.h"
34#elif defined(IS31FL3741) 34#elif defined(IS31FL3741)
35# include "is31fl3741.h" 35# include "is31fl3741.h"
36#elif defined(AW20216)
37# include "aw20216.h"
36#elif defined(WS2812) 38#elif defined(WS2812)
37# include "ws2812.h" 39# include "ws2812.h"
38#endif 40#endif
diff --git a/quantum/rgb_matrix_drivers.c b/quantum/rgb_matrix_drivers.c
index 896fa6d0e..6a11d4791 100644
--- a/quantum/rgb_matrix_drivers.c
+++ b/quantum/rgb_matrix_drivers.c
@@ -171,6 +171,22 @@ const rgb_matrix_driver_t rgb_matrix_driver = {
171}; 171};
172# endif 172# endif
173 173
174#elif defined(AW20216)
175# include "spi_master.h"
176static void init(void) {
177 spi_init();
178 AW20216_init();
179}
180
181static void flush(void) { AW20216_update_pwm_buffers(); }
182
183const rgb_matrix_driver_t rgb_matrix_driver = {
184 .init = init,
185 .flush = flush,
186 .set_color = AW20216_set_color,
187 .set_color_all = AW20216_set_color_all,
188};
189
174#elif defined(WS2812) 190#elif defined(WS2812)
175# if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_CUSTOM_DRIVER) 191# if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_CUSTOM_DRIVER)
176# pragma message "Cannot use RGBLIGHT and RGB Matrix using WS2812 at the same time." 192# pragma message "Cannot use RGBLIGHT and RGB Matrix using WS2812 at the same time."