summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Brassel <nick@tzarc.org>2022-06-20 14:20:56 +1000
committerGitHub <noreply@github.com>2022-06-20 14:20:56 +1000
commitaa06893b58ac3ed88e796968d237f60f4c156875 (patch)
treead4b3a637b7bba88de772dd50150262d2992603e
parentad2e85361128a2252798a7bb4c1cbc0bcd58e8ab (diff)
Add Djinn. (#17382)
* Add Djinn. * Review comments. * Further cleanup.
-rw-r--r--.gitignore4
-rw-r--r--keyboards/tzarc/djinn/config.h74
-rw-r--r--keyboards/tzarc/djinn/djinn.c199
-rw-r--r--keyboards/tzarc/djinn/djinn.h32
-rw-r--r--keyboards/tzarc/djinn/djinn_portscan_matrix.c117
-rw-r--r--keyboards/tzarc/djinn/djinn_split_sync.c58
-rw-r--r--keyboards/tzarc/djinn/djinn_usbpd.c28
-rw-r--r--keyboards/tzarc/djinn/graphics/djinn.qgf.c246
-rw-r--r--keyboards/tzarc/djinn/graphics/djinn.qgf.h11
-rw-r--r--keyboards/tzarc/djinn/graphics/lock-caps-OFF.qgf.c31
-rw-r--r--keyboards/tzarc/djinn/graphics/lock-caps-OFF.qgf.h11
-rw-r--r--keyboards/tzarc/djinn/graphics/lock-caps-ON.qgf.c32
-rw-r--r--keyboards/tzarc/djinn/graphics/lock-caps-ON.qgf.h11
-rw-r--r--keyboards/tzarc/djinn/graphics/lock-num-OFF.qgf.c31
-rw-r--r--keyboards/tzarc/djinn/graphics/lock-num-OFF.qgf.h11
-rw-r--r--keyboards/tzarc/djinn/graphics/lock-num-ON.qgf.c32
-rw-r--r--keyboards/tzarc/djinn/graphics/lock-num-ON.qgf.h11
-rw-r--r--keyboards/tzarc/djinn/graphics/lock-scrl-OFF.qgf.c32
-rw-r--r--keyboards/tzarc/djinn/graphics/lock-scrl-OFF.qgf.h11
-rw-r--r--keyboards/tzarc/djinn/graphics/lock-scrl-ON.qgf.c32
-rw-r--r--keyboards/tzarc/djinn/graphics/lock-scrl-ON.qgf.h11
-rw-r--r--keyboards/tzarc/djinn/graphics/theme_djinn_default.c307
-rw-r--r--keyboards/tzarc/djinn/graphics/theme_djinn_default.h19
-rw-r--r--keyboards/tzarc/djinn/graphics/thintel15.qff.c74
-rw-r--r--keyboards/tzarc/djinn/graphics/thintel15.qff.h11
-rw-r--r--keyboards/tzarc/djinn/halconf.h14
-rw-r--r--keyboards/tzarc/djinn/info.json140
-rw-r--r--keyboards/tzarc/djinn/keymaps/default/config.h60
-rw-r--r--keyboards/tzarc/djinn/keymaps/default/keymap.c107
-rw-r--r--keyboards/tzarc/djinn/keymaps/default/rules.mk15
-rw-r--r--keyboards/tzarc/djinn/mcuconf.h30
-rw-r--r--keyboards/tzarc/djinn/readme.md27
-rw-r--r--keyboards/tzarc/djinn/rev1/config.h35
-rw-r--r--keyboards/tzarc/djinn/rev1/info.json98
-rw-r--r--keyboards/tzarc/djinn/rev1/rev1.c3
-rw-r--r--keyboards/tzarc/djinn/rev1/rev1.h3
-rw-r--r--keyboards/tzarc/djinn/rev1/rules.mk1
-rw-r--r--keyboards/tzarc/djinn/rev2/config.h47
-rw-r--r--keyboards/tzarc/djinn/rev2/info.json100
-rw-r--r--keyboards/tzarc/djinn/rev2/rev2.c3
-rw-r--r--keyboards/tzarc/djinn/rev2/rev2.h3
-rw-r--r--keyboards/tzarc/djinn/rev2/rules.mk1
-rw-r--r--keyboards/tzarc/djinn/rules.mk23
43 files changed, 2145 insertions, 1 deletions
diff --git a/.gitignore b/.gitignore
index b1bd2609bc..e9bf3c2205 100644
--- a/.gitignore
+++ b/.gitignore
@@ -67,10 +67,12 @@ CMakeLists.txt
67.vscode/temp.sql 67.vscode/temp.sql
68tags 68tags
69 69
70# Ignore image files 70# Ignore image/font files
71*.gif 71*.gif
72*.jpg 72*.jpg
73*.png 73*.png
74*.ttf
75*.otf
74 76
75# Things Travis sees 77# Things Travis sees
76/.vs 78/.vs
diff --git a/keyboards/tzarc/djinn/config.h b/keyboards/tzarc/djinn/config.h
new file mode 100644
index 0000000000..005784b98d
--- /dev/null
+++ b/keyboards/tzarc/djinn/config.h
@@ -0,0 +1,74 @@
1// Copyright 2018-2022 Nick Brassel (@tzarc)
2// SPDX-License-Identifier: GPL-2.0-or-later
3#pragma once
4#include "config_common.h"
5
6// Encoders -- right-side is reversed
7#define ENCODERS_PAD_A \
8 { C14 }
9#define ENCODERS_PAD_B \
10 { C15 }
11#define ENCODERS_PAD_A_RIGHT \
12 { C15 }
13#define ENCODERS_PAD_B_RIGHT \
14 { C14 }
15
16#ifndef ENCODER_RESOLUTION
17# define ENCODER_RESOLUTION 2
18#endif // ENCODER_RESOLUTION
19
20// Bootloader
21#define STM32_BOOTLOADER_DUAL_BANK TRUE
22#define STM32_BOOTLOADER_DUAL_BANK_GPIO B7
23
24// Peripheral power control pins
25#define LCD_POWER_ENABLE_PIN A6
26
27// Split configuration
28#define SPLIT_TRANSACTION_IDS_KB RPC_ID_SYNC_STATE_KB
29#define SPLIT_TRANSPORT_MIRROR
30#define SPLIT_LAYER_STATE_ENABLE
31#define SPLIT_LED_STATE_ENABLE
32#define SPLIT_MODS_ENABLE
33#define SPLIT_WPM_ENABLE
34
35// SPI Configuration
36#define SPI_DRIVER SPID3
37#define SPI_SCK_PIN C10
38#define SPI_SCK_PAL_MODE 6
39#define SPI_MOSI_PIN C12
40#define SPI_MOSI_PAL_MODE 6
41#define SPI_MISO_PIN C11
42#define SPI_MISO_PAL_MODE 6
43
44// LCD Configuration
45#define LCD_RST_PIN B3
46#define LCD_CS_PIN D2
47#define LCD_DC_PIN A15
48#ifndef LCD_ACTIVITY_TIMEOUT
49# define LCD_ACTIVITY_TIMEOUT 30000
50#endif // LCD_ACTIVITY_TIMEOUT
51
52// Backlight driver (to control LCD backlight)
53#define BACKLIGHT_LEVELS 4
54#define BACKLIGHT_PWM_DRIVER PWMD17
55#define BACKLIGHT_PWM_CHANNEL 1
56#define BACKLIGHT_PAL_MODE 1
57
58// RGB configuration
59#define RGB_DI_PIN B2
60#define WS2812_EXTERNAL_PULLUP
61#define WS2812_PWM_DRIVER PWMD20
62#define WS2812_PWM_CHANNEL 1
63#define WS2812_PWM_PAL_MODE 3
64#define WS2812_DMA_STREAM STM32_DMA1_STREAM1
65#define WS2812_DMA_CHANNEL 1
66#define WS2812_DMAMUX_ID STM32_DMAMUX1_TIM20_UP
67
68// Audio configuration
69#define AUDIO_PIN A5
70#define AUDIO_PIN_ALT A4
71#define AUDIO_PIN_ALT_AS_NEGATIVE
72#ifndef STARTUP_SONG
73# define STARTUP_SONG SONG(STARTUP_SOUND)
74#endif // STARTUP_SONG
diff --git a/keyboards/tzarc/djinn/djinn.c b/keyboards/tzarc/djinn/djinn.c
new file mode 100644
index 0000000000..41155a6584
--- /dev/null
+++ b/keyboards/tzarc/djinn/djinn.c
@@ -0,0 +1,199 @@
1// Copyright 2018-2022 Nick Brassel (@tzarc)
2// SPDX-License-Identifier: GPL-2.0-or-later
3#include <string.h>
4#include "quantum.h"
5#include <hal_pal.h>
6#include "djinn.h"
7#include "serial.h"
8#include "split_util.h"
9#include "qp.h"
10
11painter_device_t lcd;
12
13// clang-format off
14#ifdef SWAP_HANDS_ENABLE
15const keypos_t PROGMEM hand_swap_config[MATRIX_ROWS][MATRIX_COLS] = {
16 { { 6, 6 }, { 5, 6 }, { 4, 6 }, { 3, 6 }, { 2, 6 }, { 1, 6 }, { 0, 6 } },
17 { { 6, 7 }, { 5, 7 }, { 4, 7 }, { 3, 7 }, { 2, 7 }, { 1, 7 }, { 0, 7 } },
18 { { 6, 8 }, { 5, 8 }, { 4, 8 }, { 3, 8 }, { 2, 8 }, { 1, 8 }, { 0, 8 } },
19 { { 6, 9 }, { 5, 9 }, { 4, 9 }, { 3, 9 }, { 2, 9 }, { 1, 9 }, { 0, 9 } },
20 { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 6, 10 }, { 5, 10 }, { 4, 10 }, { 3, 10 } },
21 { { 0, 0 }, { 6, 11 }, { 5, 11 }, { 4, 11 }, { 3, 11 }, { 2, 11 }, { 1, 11 } },
22
23 { { 6, 0 }, { 5, 0 }, { 4, 0 }, { 3, 0 }, { 2, 0 }, { 1, 0 }, { 0, 0 } },
24 { { 6, 1 }, { 5, 1 }, { 4, 1 }, { 3, 1 }, { 2, 1 }, { 1, 1 }, { 0, 1 } },
25 { { 6, 2 }, { 5, 2 }, { 4, 2 }, { 3, 2 }, { 2, 2 }, { 1, 2 }, { 0, 2 } },
26 { { 6, 3 }, { 5, 3 }, { 4, 3 }, { 3, 3 }, { 2, 3 }, { 1, 3 }, { 0, 3 } },
27 { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 6, 4 }, { 5, 4 }, { 4, 4 }, { 3, 4 } },
28 { { 0, 0 }, { 6, 5 }, { 5, 5 }, { 4, 5 }, { 3, 5 }, { 2, 5 }, { 1, 5 } },
29};
30# ifdef ENCODER_MAP_ENABLE
31const uint8_t PROGMEM encoder_hand_swap_config[NUM_ENCODERS] = { 1, 0 };
32# endif // ENCODER_MAP_ENABLE
33#endif // SWAP_HANDS_ENABLE
34// clang-format on
35
36void board_init(void) {
37 usbpd_init();
38}
39
40//----------------------------------------------------------
41// Initialisation
42
43void keyboard_post_init_kb(void) {
44 // Register keyboard state sync split transaction
45 transaction_register_rpc(RPC_ID_SYNC_STATE_KB, kb_state_sync_slave);
46
47 // Reset the initial shared data value between master and slave
48 memset(&kb_state, 0, sizeof(kb_state));
49
50 // Turn off increased current limits
51 setPinOutput(RGB_CURR_1500mA_OK_PIN);
52 writePinLow(RGB_CURR_1500mA_OK_PIN);
53 setPinOutput(RGB_CURR_3000mA_OK_PIN);
54 writePinLow(RGB_CURR_3000mA_OK_PIN);
55
56 // Turn on the RGB
57 setPinOutput(RGB_POWER_ENABLE_PIN);
58 writePinHigh(RGB_POWER_ENABLE_PIN);
59
60#ifdef EXTERNAL_FLASH_SPI_SLAVE_SELECT_PIN
61 setPinOutput(EXTERNAL_FLASH_SPI_SLAVE_SELECT_PIN);
62 writePinHigh(EXTERNAL_FLASH_SPI_SLAVE_SELECT_PIN);
63#endif // EXTERNAL_FLASH_SPI_SLAVE_SELECT_PIN
64
65 // Turn on the LCD
66 setPinOutput(LCD_POWER_ENABLE_PIN);
67 writePinHigh(LCD_POWER_ENABLE_PIN);
68
69 // Let the LCD get some power...
70 wait_ms(150);
71
72 // Initialise the LCD
73 lcd = qp_ili9341_make_spi_device(320, 240, LCD_CS_PIN, LCD_DC_PIN, LCD_RST_PIN, 4, 3);
74 qp_init(lcd, QP_ROTATION_0);
75
76 // Turn on the LCD and clear the display
77 kb_state.lcd_power = 1;
78 qp_power(lcd, true);
79 qp_rect(lcd, 0, 0, 239, 319, HSV_BLACK, true);
80
81 // Turn on the LCD backlight
82 backlight_enable();
83 backlight_level(BACKLIGHT_LEVELS);
84
85 // Allow for user post-init
86 keyboard_post_init_user();
87}
88
89//----------------------------------------------------------
90// RGB brightness scaling dependent on USBPD state
91
92#if defined(RGB_MATRIX_ENABLE)
93RGB rgb_matrix_hsv_to_rgb(HSV hsv) {
94 float scale;
95 switch (kb_state.current_setting) {
96 default:
97 case USBPD_500MA:
98 scale = 0.35f;
99 break;
100 case USBPD_1500MA:
101 scale = 0.75f;
102 break;
103 case USBPD_3000MA:
104 scale = 1.0f;
105 break;
106 }
107
108 hsv.v = (uint8_t)(hsv.v * scale);
109 return hsv_to_rgb(hsv);
110}
111#endif
112
113//----------------------------------------------------------
114// UI Placeholder, implemented in themes
115
116__attribute__((weak)) void draw_ui_user(void) {}
117
118//----------------------------------------------------------
119// Housekeeping
120
121void housekeeping_task_kb(void) {
122 // Update kb_state so we can send to slave
123 kb_state_update();
124
125 // Data sync from master to slave
126 kb_state_sync();
127
128 // Work out if we've changed our current limit, update the limiter circuit switches
129 static uint8_t current_setting = USBPD_500MA;
130 if (current_setting != kb_state.current_setting) {
131 current_setting = kb_state.current_setting;
132 switch (current_setting) {
133 default:
134 case USBPD_500MA:
135 writePinLow(RGB_CURR_1500mA_OK_PIN);
136 writePinLow(RGB_CURR_3000mA_OK_PIN);
137 break;
138 case USBPD_1500MA:
139 writePinHigh(RGB_CURR_1500mA_OK_PIN);
140 writePinLow(RGB_CURR_3000mA_OK_PIN);
141 break;
142 case USBPD_3000MA:
143 writePinHigh(RGB_CURR_1500mA_OK_PIN);
144 writePinHigh(RGB_CURR_3000mA_OK_PIN);
145 break;
146 }
147
148 // If we've changed the current limit, toggle rgb off and on if it was on, to force a brightness update on all LEDs
149 if (is_keyboard_master() && rgb_matrix_is_enabled()) {
150 rgb_matrix_disable_noeeprom();
151 rgb_matrix_enable_noeeprom();
152 }
153 }
154
155 // Turn on/off the LCD
156 static bool lcd_on = false;
157 if (lcd_on != (bool)kb_state.lcd_power) {
158 lcd_on = (bool)kb_state.lcd_power;
159 qp_power(lcd, lcd_on);
160 }
161
162 // Enable/disable RGB
163 if (lcd_on) {
164 // Turn on RGB
165 writePinHigh(RGB_POWER_ENABLE_PIN);
166 // Modify the RGB state if different to the LCD state
167 if (rgb_matrix_is_enabled() != lcd_on) {
168 // Wait for a small amount of time to allow the RGB capacitors to charge, before enabling RGB output
169 wait_ms(10);
170 // Enable RGB
171 rgb_matrix_enable_noeeprom();
172 }
173 } else {
174 // Turn off RGB
175 writePinLow(RGB_POWER_ENABLE_PIN);
176 // Disable the PWM output for the RGB
177 if (rgb_matrix_is_enabled() != lcd_on) {
178 rgb_matrix_disable_noeeprom();
179 }
180 }
181
182 // Match the backlight to the LCD state
183 if (is_keyboard_master() && is_backlight_enabled() != lcd_on) {
184 if (lcd_on)
185 backlight_enable();
186 else
187 backlight_disable();
188 }
189
190 // Draw the UI
191 if (kb_state.lcd_power) {
192 draw_ui_user();
193 }
194
195 // Go into low-scan interrupt-based mode if we haven't had any matrix activity in the last 250 milliseconds
196 if (last_input_activity_elapsed() > 250) {
197 matrix_wait_for_interrupt();
198 }
199} \ No newline at end of file
diff --git a/keyboards/tzarc/djinn/djinn.h b/keyboards/tzarc/djinn/djinn.h
new file mode 100644
index 0000000000..ff6b555e8e
--- /dev/null
+++ b/keyboards/tzarc/djinn/djinn.h
@@ -0,0 +1,32 @@
1// Copyright 2018-2022 Nick Brassel (@tzarc)
2// SPDX-License-Identifier: GPL-2.0-or-later
3#pragma once
4#include "quantum.h"
5#include "qp.h"
6
7//----------------------------------------------------------
8// General stuff
9
10extern painter_device_t lcd;
11
12void matrix_wait_for_interrupt(void);
13
14void usbpd_update(void);
15const char* usbpd_str(usbpd_allowance_t allowance);
16
17//----------------------------------------------------------
18// Runtime data sync -- keyboard
19
20#pragma pack(push)
21#pragma pack(1)
22typedef struct kb_runtime_config {
23 unsigned lcd_power : 1;
24 usbpd_allowance_t current_setting : 2;
25} kb_runtime_config;
26#pragma pack(pop)
27
28extern kb_runtime_config kb_state;
29
30void kb_state_update(void);
31void kb_state_sync(void);
32void kb_state_sync_slave(uint8_t m2s_size, const void* m2s_buffer, uint8_t s2m_size, void* s2m_buffer);
diff --git a/keyboards/tzarc/djinn/djinn_portscan_matrix.c b/keyboards/tzarc/djinn/djinn_portscan_matrix.c
new file mode 100644
index 0000000000..f0ae9721f9
--- /dev/null
+++ b/keyboards/tzarc/djinn/djinn_portscan_matrix.c
@@ -0,0 +1,117 @@
1// Copyright 2018-2022 Nick Brassel (@tzarc)
2// SPDX-License-Identifier: GPL-2.0-or-later
3#include "quantum.h"
4#include <hal_pal.h>
5#include "djinn.h"
6
7#define GPIOB_BITMASK (1 << 13 | 1 << 14 | 1 << 15) // B13, B14, B15
8#define GPIOB_OFFSET 13
9#define GPIOB_COUNT 3
10#define GPIOC_BITMASK (1 << 6 | 1 << 7 | 1 << 8) // C6, C7, C8
11#define GPIOC_OFFSET 6
12
13// Pin definitions
14static const pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS;
15static const pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS;
16
17void matrix_wait_for_pin(pin_t pin, uint8_t target_state) {
18 rtcnt_t start = chSysGetRealtimeCounterX();
19 rtcnt_t end = start + 5000;
20 while (chSysIsCounterWithinX(chSysGetRealtimeCounterX(), start, end)) {
21 if (readPin(pin) == target_state) {
22 break;
23 }
24 }
25}
26
27void matrix_wait_for_port(stm32_gpio_t *port, uint32_t target_bitmask) {
28 rtcnt_t start = chSysGetRealtimeCounterX();
29 rtcnt_t end = start + 5000;
30 while (chSysIsCounterWithinX(chSysGetRealtimeCounterX(), start, end)) {
31 if ((palReadPort(port) & target_bitmask) == target_bitmask) {
32 break;
33 }
34 }
35}
36
37void matrix_init_custom(void) {
38 for (int i = 0; i < MATRIX_ROWS; ++i) {
39 setPinInputHigh(row_pins[i]);
40 }
41 for (int i = 0; i < MATRIX_COLS; ++i) {
42 setPinInputHigh(col_pins[i]);
43 }
44}
45
46bool matrix_scan_custom(matrix_row_t current_matrix[]) {
47 static matrix_row_t temp_matrix[MATRIX_ROWS] = {0};
48
49 for (int current_col = 0; current_col < MATRIX_COLS; ++current_col) {
50 // Keep track of the pin we're working with
51 pin_t curr_col_pin = col_pins[current_col];
52
53 // Setup the output column pin
54 setPinOutput(curr_col_pin);
55 writePinLow(curr_col_pin);
56 matrix_wait_for_pin(curr_col_pin, 0);
57
58 // Read the row ports
59 uint32_t gpio_b = palReadPort(GPIOB);
60 uint32_t gpio_c = palReadPort(GPIOC);
61
62 // Unselect the row pin
63 setPinInputHigh(curr_col_pin);
64
65 // Construct the packed bitmask for the pins
66 uint32_t readback = ~(((gpio_b & GPIOB_BITMASK) >> GPIOB_OFFSET) | (((gpio_c & GPIOC_BITMASK) >> GPIOC_OFFSET) << GPIOB_COUNT));
67
68 // Inject values into the matrix
69 for (int i = 0; i < MATRIX_ROWS; ++i) {
70 if (readback & (1 << i)) {
71 temp_matrix[i] |= (1ul << current_col);
72 } else {
73 temp_matrix[i] &= ~(1ul << current_col);
74 }
75 }
76
77 // Wait for readback of the unselected column to go high
78 matrix_wait_for_pin(curr_col_pin, 1);
79
80 // Wait for readback of each port to go high -- unselecting the row would have been completed
81 matrix_wait_for_port(GPIOB, GPIOB_BITMASK);
82 matrix_wait_for_port(GPIOC, GPIOC_BITMASK);
83 }
84
85 // Check if we've changed, return the last-read data
86 bool changed = memcmp(current_matrix, temp_matrix, sizeof(temp_matrix)) != 0;
87 if (changed) {
88 memcpy(current_matrix, temp_matrix, sizeof(temp_matrix));
89 }
90 return changed;
91}
92
93void matrix_wait_for_interrupt(void) {
94 // Set up row/col pins and attach callback
95 for (int i = 0; i < sizeof(col_pins) / sizeof(pin_t); ++i) {
96 setPinOutput(col_pins[i]);
97 writePinLow(col_pins[i]);
98 }
99 for (int i = 0; i < sizeof(row_pins) / sizeof(pin_t); ++i) {
100 setPinInputHigh(row_pins[i]);
101 palEnableLineEvent(row_pins[i], PAL_EVENT_MODE_BOTH_EDGES);
102 }
103
104 // Wait for an interrupt
105 __WFI();
106
107 // Now that the interrupt has woken us up, reset all the row/col pins back to defaults
108 for (int i = 0; i < sizeof(row_pins) / sizeof(pin_t); ++i) {
109 palDisableLineEvent(row_pins[i]);
110 writePinHigh(row_pins[i]);
111 setPinInputHigh(row_pins[i]);
112 }
113 for (int i = 0; i < sizeof(col_pins) / sizeof(pin_t); ++i) {
114 writePinHigh(col_pins[i]);
115 setPinInputHigh(col_pins[i]);
116 }
117} \ No newline at end of file
diff --git a/keyboards/tzarc/djinn/djinn_split_sync.c b/keyboards/tzarc/djinn/djinn_split_sync.c
new file mode 100644
index 0000000000..3c7a58d155
--- /dev/null
+++ b/keyboards/tzarc/djinn/djinn_split_sync.c
@@ -0,0 +1,58 @@
1// Copyright 2018-2022 Nick Brassel (@tzarc)
2// SPDX-License-Identifier: GPL-2.0-or-later
3#include <string.h>
4#include "quantum.h"
5#include "transactions.h"
6#include "split_util.h"
7#include "djinn.h"
8
9kb_runtime_config kb_state;
10uint32_t last_slave_sync_time = 0;
11
12void kb_state_update(void) {
13 if (is_keyboard_master()) {
14 // Modify allowed current limits
15 usbpd_update();
16
17 // Turn off the LCD if there's been no matrix activity
18 kb_state.lcd_power = (last_input_activity_elapsed() < LCD_ACTIVITY_TIMEOUT) ? 1 : 0;
19 }
20}
21
22void kb_state_sync(void) {
23 if (!is_transport_connected()) return;
24
25 if (is_keyboard_master()) {
26 // Keep track of the last state, so that we can tell if we need to propagate to slave
27 static kb_runtime_config last_kb_state;
28 static uint32_t last_sync;
29 bool needs_sync = false;
30
31 // Check if the state values are different
32 if (memcmp(&kb_state, &last_kb_state, sizeof(kb_runtime_config))) {
33 needs_sync = true;
34 memcpy(&last_kb_state, &kb_state, sizeof(kb_runtime_config));
35 }
36
37 // Send to slave every 500ms regardless of state change
38 if (timer_elapsed32(last_sync) > 500) {
39 needs_sync = true;
40 }
41
42 // Perform the sync if requested
43 if (needs_sync) {
44 if (transaction_rpc_send(RPC_ID_SYNC_STATE_KB, sizeof(kb_runtime_config), &kb_state)) {
45 last_sync = timer_read32();
46 } else {
47 dprint("Failed to perform data transaction\n");
48 }
49 }
50 }
51}
52
53void kb_state_sync_slave(uint8_t m2s_size, const void* m2s_buffer, uint8_t s2m_size, void* s2m_buffer) {
54 if (m2s_size == sizeof(kb_runtime_config)) {
55 memcpy(&kb_state, m2s_buffer, sizeof(kb_runtime_config));
56 last_slave_sync_time = timer_read32();
57 }
58}
diff --git a/keyboards/tzarc/djinn/djinn_usbpd.c b/keyboards/tzarc/djinn/djinn_usbpd.c
new file mode 100644
index 0000000000..b0bf166b7c
--- /dev/null
+++ b/keyboards/tzarc/djinn/djinn_usbpd.c
@@ -0,0 +1,28 @@
1// Copyright 2018-2022 Nick Brassel (@tzarc)
2// SPDX-License-Identifier: GPL-2.0-or-later
3#include <string.h>
4#include "quantum.h"
5#include "djinn.h"
6
7const char* usbpd_str(usbpd_allowance_t allowance) {
8 switch (allowance) {
9 default:
10 case USBPD_500MA:
11 return "500mA";
12 case USBPD_1500MA:
13 return "1500mA";
14 case USBPD_3000MA:
15 return "3000mA";
16 }
17}
18
19void usbpd_update(void) {
20 static uint32_t last_read = 0;
21 if (timer_elapsed32(last_read) > 250) {
22 usbpd_allowance_t allowance = usbpd_get_allowance();
23 if (kb_state.current_setting != allowance) {
24 dprintf("Transitioning UCPD1 %s -> %s\n", usbpd_str(kb_state.current_setting), usbpd_str(allowance));
25 kb_state.current_setting = allowance;
26 }
27 }
28} \ No newline at end of file
diff --git a/keyboards/tzarc/djinn/graphics/djinn.qgf.c b/keyboards/tzarc/djinn/graphics/djinn.qgf.c
new file mode 100644
index 0000000000..0acdf6ebb5
--- /dev/null
+++ b/keyboards/tzarc/djinn/graphics/djinn.qgf.c
@@ -0,0 +1,246 @@
1// Copyright 2022 QMK -- generated source code only, image retains original copyright
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4// This file was auto-generated by `qmk painter-convert-graphics -i djinn.png -f mono4`
5
6#include <qp.h>
7
8const uint32_t gfx_djinn_length = 3724;
9
10// clang-format off
11const uint8_t gfx_djinn[3724] = {
12 0x00, 0xFF, 0x12, 0x00, 0x00, 0x51, 0x47, 0x46, 0x01, 0x8C, 0x0E, 0x00, 0x00, 0x73, 0xF1, 0xFF,
13 0xFF, 0x66, 0x00, 0x20, 0x01, 0x01, 0x00, 0x01, 0xFE, 0x04, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
14 0x02, 0xFD, 0x06, 0x00, 0x00, 0x01, 0x00, 0x01, 0xFF, 0xE8, 0x03, 0x05, 0xFA, 0x5C, 0x0E, 0x00,
15 0x58, 0x00, 0x80, 0x90, 0x19, 0x00, 0x80, 0x2D, 0x18, 0x00, 0x81, 0xE0, 0x07, 0x18, 0x00, 0x81,
16 0xFE, 0x01, 0x17, 0x00, 0x81, 0xF4, 0x2F, 0x17, 0x00, 0x82, 0x80, 0xFF, 0x07, 0x17, 0x00, 0x82,
17 0xFD, 0xFF, 0x01, 0x16, 0x00, 0x82, 0xE0, 0xFF, 0x2F, 0x16, 0x00, 0x80, 0x80, 0x02, 0xFF, 0x80,
18 0x03, 0x15, 0x00, 0x84, 0x40, 0xFE, 0xFF, 0x7F, 0x14, 0x15, 0x00, 0x80, 0xF9, 0x02, 0xFF, 0x81,
19 0x4B, 0x1A, 0x14, 0x00, 0x80, 0xE4, 0x03, 0xFF, 0x81, 0xE0, 0x06, 0x13, 0x00, 0x80, 0xD0, 0x03,
20 0xFF, 0x82, 0x0F, 0xBE, 0x01, 0x12, 0x00, 0x80, 0x80, 0x04, 0xFF, 0x81, 0xE0, 0x6F, 0x13, 0x00,
21 0x80, 0xFE, 0x03, 0xFF, 0x82, 0x0F, 0xFE, 0x0B, 0x12, 0x00, 0x80, 0xF8, 0x04, 0xFF, 0x82, 0xE0,
22 0xFF, 0x02, 0x11, 0x00, 0x80, 0xE0, 0x04, 0xFF, 0x82, 0x0F, 0xFE, 0xBF, 0x11, 0x00, 0x80, 0x80,
23 0x04, 0xFF, 0x83, 0xBF, 0xF4, 0xFF, 0x1F, 0x11, 0x00, 0x80, 0xFE, 0x04, 0xFF, 0x80, 0x47, 0x02,
24 0xFF, 0x80, 0x07, 0x10, 0x00, 0x80, 0xF4, 0x04, 0xFF, 0x83, 0x2F, 0xF8, 0xFF, 0xBF, 0x10, 0x00,
25 0x80, 0xD0, 0x05, 0xFF, 0x80, 0xD1, 0x02, 0xFF, 0x80, 0x1F, 0x0F, 0x00, 0x81, 0x40, 0xFE, 0x04,
26 0xFF, 0x81, 0x0B, 0xFE, 0x02, 0xFF, 0x80, 0x06, 0x0F, 0x00, 0x80, 0xF8, 0x04, 0xFF, 0x81, 0x2F,
27 0xF4, 0x02, 0xFF, 0x80, 0xBF, 0x0F, 0x00, 0x80, 0xE0, 0x04, 0xFF, 0x81, 0xBF, 0xD0, 0x03, 0xFF,
28 0x80, 0x1F, 0x0E, 0x00, 0x80, 0x40, 0x04, 0xFF, 0x81, 0xBF, 0x41, 0x04, 0xFF, 0x80, 0x06, 0x0E,
29 0x00, 0x80, 0xF8, 0x04, 0xFF, 0x81, 0x06, 0xFD, 0x03, 0xFF, 0x80, 0x7F, 0x0E, 0x00, 0x80, 0xE0,
30 0x04, 0xFF, 0x81, 0x06, 0x90, 0x04, 0xFF, 0x80, 0x0B, 0x0D, 0x00, 0x80, 0x40, 0x04, 0xFF, 0x82,
31 0x1B, 0x00, 0xE4, 0x04, 0xFF, 0x80, 0x01, 0x0D, 0x00, 0x80, 0xF8, 0x03, 0xFF, 0x80, 0x1B, 0x02,
32 0x00, 0x80, 0xE4, 0x03, 0xFF, 0x80, 0x2F, 0x0D, 0x00, 0x80, 0xD0, 0x03, 0xFF, 0x80, 0x5B, 0x03,
33 0x00, 0x80, 0xE4, 0x03, 0xFF, 0x80, 0x07, 0x0D, 0x00, 0x80, 0xFE, 0x02, 0xFF, 0x80, 0x6F, 0x04,
34 0x00, 0x80, 0xF9, 0x02, 0xFF, 0x80, 0x7F, 0x0D, 0x00, 0x80, 0xE0, 0x02, 0xFF, 0x80, 0x7F, 0x05,
35 0x00, 0x80, 0xFD, 0x02, 0xFF, 0x80, 0x0B, 0x0C, 0x00, 0x80, 0x40, 0x02, 0xFF, 0x81, 0xBF, 0x01,
36 0x04, 0x00, 0x81, 0x40, 0xFE, 0x02, 0xFF, 0x0D, 0x00, 0x80, 0xF8, 0x02, 0xFF, 0x80, 0x02, 0x05,
37 0x00, 0x80, 0x90, 0x02, 0xFF, 0x80, 0x0F, 0x0C, 0x00, 0x80, 0x80, 0x02, 0xFF, 0x80, 0x07, 0x06,
38 0x00, 0x80, 0xF4, 0x02, 0xFF, 0x0D, 0x00, 0x82, 0xFD, 0xFF, 0x1F, 0x07, 0x00, 0x82, 0xFD, 0xFF,
39 0x1F, 0x0C, 0x00, 0x82, 0xD0, 0xFF, 0x7F, 0x07, 0x00, 0x80, 0x80, 0x02, 0xFF, 0x80, 0x01, 0x0C,
40 0x00, 0x82, 0xFD, 0xFF, 0x02, 0x07, 0x00, 0x82, 0xF4, 0xFF, 0x1F, 0x0C, 0x00, 0x82, 0xE0, 0xFF,
41 0x0B, 0x08, 0x00, 0x82, 0xFE, 0xFF, 0x01, 0x0C, 0x00, 0x81, 0xFE, 0x7F, 0x08, 0x00, 0x82, 0xD0,
42 0xFF, 0x1F, 0x0C, 0x00, 0x82, 0xE0, 0xFF, 0x02, 0x08, 0x00, 0x81, 0xF8, 0xFF, 0x0D, 0x00, 0x81,
43 0xFE, 0x1F, 0x08, 0x00, 0x82, 0x40, 0xFF, 0x0F, 0x0C, 0x00, 0x82, 0xE0, 0xFF, 0x01, 0x08, 0x00,
44 0x81, 0xF4, 0xFF, 0x0D, 0x00, 0x81, 0xFD, 0x0B, 0x09, 0x00, 0x81, 0xFE, 0x0B, 0x0C, 0x00, 0x81,
45 0xD0, 0xBF, 0x09, 0x00, 0x81, 0xE0, 0xBF, 0x0D, 0x00, 0x81, 0xF9, 0x07, 0x09, 0x00, 0x81, 0xFD,
46 0x07, 0x0C, 0x00, 0x81, 0x80, 0x7F, 0x09, 0x00, 0x81, 0xD0, 0x7F, 0x0D, 0x00, 0x81, 0xF8, 0x07,
47 0x09, 0x00, 0x81, 0xF9, 0x03, 0x0C, 0x00, 0x81, 0x40, 0x7F, 0x09, 0x00, 0x81, 0x90, 0x2F, 0x0D,
48 0x00, 0x81, 0xE0, 0x07, 0x09, 0x00, 0x81, 0xF8, 0x02, 0x0D, 0x00, 0x80, 0x7D, 0x09, 0x00, 0x81,
49 0x80, 0x1F, 0x0D, 0x00, 0x81, 0x80, 0x07, 0x09, 0x00, 0x80, 0xB8, 0x0E, 0x00, 0x80, 0x74, 0x09,
50 0x00, 0x81, 0x80, 0x0B, 0x0E, 0x00, 0x80, 0x0A, 0x03, 0x00, 0x80, 0x04, 0x05, 0x00, 0x80, 0x78,
51 0x0E, 0x00, 0x80, 0x90, 0x03, 0x00, 0x83, 0xA4, 0x00, 0x80, 0x06, 0x02, 0x00, 0x81, 0x80, 0x02,
52 0x0E, 0x00, 0x87, 0x04, 0x00, 0x40, 0xE9, 0x0B, 0x00, 0xF8, 0x5A, 0x02, 0x00, 0x80, 0x14, 0x10,
53 0x00, 0x86, 0x40, 0xFA, 0xBF, 0x00, 0x40, 0xFF, 0x6B, 0x12, 0x00, 0x87, 0x90, 0xFE, 0xFF, 0x07,
54 0x00, 0xE0, 0xFF, 0xAF, 0x11, 0x00, 0x80, 0x80, 0x02, 0xFF, 0x80, 0x1F, 0x02, 0x00, 0x82, 0xF9,
55 0xFF, 0x2F, 0x11, 0x00, 0x82, 0xFE, 0xFF, 0x6F, 0x03, 0x00, 0x82, 0xFD, 0xFF, 0x0B, 0x10, 0x00,
56 0x82, 0xF8, 0xFF, 0x7F, 0x03, 0x00, 0x82, 0x40, 0xFE, 0xFF, 0x10, 0x00, 0x83, 0xD0, 0xFF, 0xBF,
57 0x01, 0x03, 0x00, 0x82, 0x80, 0xFF, 0x1F, 0x10, 0x00, 0x82, 0xFD, 0xFF, 0x02, 0x04, 0x00, 0x82,
58 0xD0, 0xFF, 0x02, 0x0F, 0x00, 0x82, 0xE0, 0xFF, 0x0B, 0x05, 0x00, 0x81, 0xF8, 0x2F, 0x0F, 0x00,
59 0x82, 0x40, 0xFF, 0x2F, 0x06, 0x00, 0x81, 0xFE, 0x02, 0x0F, 0x00, 0x89, 0xF4, 0xFF, 0x01, 0x00,
60 0x50, 0x55, 0x05, 0x00, 0xD0, 0x7F, 0x0F, 0x00, 0x84, 0x40, 0xFF, 0x07, 0x00, 0xA4, 0x02, 0xAA,
61 0x02, 0x00, 0x81, 0xF8, 0x07, 0x0F, 0x00, 0x81, 0xF4, 0x6F, 0x02, 0x00, 0x85, 0xFE, 0xFF, 0x07,
62 0x00, 0x40, 0x7F, 0x0F, 0x00, 0x8A, 0x40, 0xFF, 0x81, 0x00, 0x80, 0xFF, 0x1F, 0x00, 0x40, 0xE0,
63 0x0B, 0x0F, 0x00, 0x85, 0xF4, 0x1B, 0x1E, 0x00, 0xF0, 0xBF, 0x02, 0x00, 0x81, 0x19, 0xBD, 0x0F,
64 0x00, 0x8B, 0x80, 0xBF, 0xF0, 0x02, 0x00, 0xFD, 0x07, 0x00, 0xE0, 0xC2, 0x0B, 0x05, 0x0E, 0x00,
65 0x8A, 0xF8, 0x47, 0xBF, 0x00, 0x80, 0x2F, 0x00, 0x40, 0x7F, 0xB8, 0x61, 0x0E, 0x00, 0x8B, 0x40,
66 0x6F, 0xF8, 0x1F, 0x00, 0xF4, 0x01, 0x00, 0xF9, 0x47, 0x1F, 0x1E, 0x0E, 0x00, 0x8B, 0xF4, 0x82,
67 0xFF, 0x06, 0x00, 0x19, 0x00, 0xE4, 0xBF, 0xF0, 0xD1, 0x06, 0x0D, 0x00, 0x8C, 0x40, 0x1F, 0xFD,
68 0xBF, 0x01, 0x40, 0x00, 0x90, 0xFF, 0x0B, 0x2E, 0xBD, 0x01, 0x0D, 0x00, 0x86, 0xF4, 0xE1, 0xFF,
69 0xBF, 0x01, 0x00, 0x80, 0x02, 0xFF, 0x82, 0xE0, 0x92, 0x6F, 0x0D, 0x00, 0x8C, 0x45, 0x1B, 0xFE,
70 0xFF, 0xBF, 0x05, 0x94, 0xFE, 0xFF, 0x1F, 0x2D, 0xF8, 0x1B, 0x0C, 0x00, 0x82, 0x74, 0xB4, 0xE0,
71 0x07, 0xFF, 0x83, 0xD1, 0x86, 0xFF, 0x07, 0x0B, 0x00, 0x83, 0xD0, 0x47, 0x4B, 0xFE, 0x06, 0xFF,
72 0x84, 0x2F, 0x7D, 0xF8, 0xFF, 0x06, 0x0A, 0x00, 0x83, 0x90, 0x7F, 0xB4, 0xF4, 0x07, 0xFF, 0x84,
73 0xD2, 0x47, 0xFF, 0xBF, 0x01, 0x09, 0x00, 0x83, 0x90, 0xFF, 0x87, 0x47, 0x07, 0xFF, 0x85, 0x3F,
74 0xB8, 0xF4, 0xFF, 0xBF, 0x05, 0x08, 0x00, 0x84, 0x95, 0xFF, 0x3F, 0x78, 0xF8, 0x07, 0xFF, 0x81,
75 0x83, 0x4B, 0x03, 0xFF, 0x81, 0x56, 0x15, 0x04, 0x00, 0x82, 0x50, 0x55, 0xEA, 0x02, 0xFF, 0x81,
76 0x82, 0x86, 0x07, 0xFF, 0x82, 0x7F, 0xB4, 0xE0, 0x03, 0xFF, 0x81, 0xAF, 0x6A, 0x03, 0x00, 0x81,
77 0x90, 0xFA, 0x03, 0xFF, 0x82, 0x1F, 0x2D, 0xF8, 0x07, 0xFF, 0x82, 0x0B, 0x19, 0xFE, 0x04, 0xFF,
78 0x80, 0x6F, 0x02, 0x00, 0x80, 0x40, 0x05, 0xFF, 0x02, 0xD1, 0x08, 0xFF, 0x81, 0x01, 0xE0, 0x05,
79 0xFF, 0x80, 0x1B, 0x02, 0x00, 0x80, 0xFD, 0x04, 0xFF, 0x82, 0x0B, 0x0A, 0xFE, 0x07, 0xFF, 0x81,
80 0xBF, 0x41, 0x06, 0xFF, 0x82, 0x02, 0x00, 0xE4, 0x04, 0xFF, 0x82, 0xBF, 0x10, 0xF4, 0x08, 0xFF,
81 0x80, 0xBF, 0x06, 0xFF, 0x82, 0x7F, 0x00, 0x80, 0x05, 0xFF, 0x81, 0x1F, 0xD0, 0x08, 0xFF, 0x82,
82 0xBF, 0x56, 0xF9, 0x05, 0xFF, 0x82, 0x1B, 0x00, 0xF9, 0x05, 0xFF, 0x80, 0x9B, 0x08, 0xFF, 0x80,
83 0x5A, 0x02, 0x00, 0x80, 0xF4, 0x05, 0xFF, 0x81, 0x01, 0x90, 0x05, 0xFF, 0x81, 0xAB, 0x5A, 0x04,
84 0x55, 0x80, 0xA9, 0x02, 0xAA, 0x84, 0x01, 0x40, 0x55, 0x05, 0xFD, 0x03, 0xFF, 0x84, 0xAA, 0x15,
85 0x00, 0x94, 0xFA, 0x02, 0xFF, 0x81, 0xBF, 0x56, 0x09, 0x00, 0x87, 0x95, 0xFA, 0xFF, 0x81, 0xFF,
86 0xAF, 0x6A, 0x15, 0x03, 0x00, 0x86, 0x40, 0xA5, 0xFA, 0xBF, 0x05, 0x50, 0x55, 0x03, 0xAA, 0x80,
87 0x16, 0x02, 0x00, 0x92, 0x50, 0xE9, 0xFF, 0xBF, 0x2A, 0xA4, 0x56, 0x05, 0x00, 0x54, 0x65, 0x00,
88 0x59, 0x01, 0x40, 0x55, 0x06, 0xA5, 0xFA, 0x02, 0xFF, 0x92, 0xBF, 0x5A, 0x01, 0x40, 0xA5, 0xFE,
89 0xFF, 0x5A, 0x15, 0x00, 0x01, 0x00, 0x55, 0xAA, 0xFE, 0x07, 0xE0, 0xAF, 0x56, 0x02, 0x00, 0x80,
90 0xE8, 0x03, 0xFF, 0x87, 0x6B, 0x05, 0x00, 0x95, 0xFA, 0xFF, 0xBF, 0x15, 0x03, 0x00, 0x81, 0x95,
91 0xEA, 0x02, 0xFF, 0x86, 0xBF, 0x00, 0xFE, 0xFF, 0xAF, 0x1A, 0xE0, 0x02, 0xFF, 0x84, 0xAF, 0x05,
92 0x00, 0x94, 0xFA, 0x02, 0xFF, 0x85, 0x6F, 0x01, 0x00, 0x54, 0xAA, 0xFE, 0x04, 0xFF, 0x81, 0x0B,
93 0xE0, 0x03, 0xFF, 0x80, 0x82, 0x02, 0xFF, 0x83, 0x1B, 0x00, 0x50, 0xFA, 0x03, 0xFF, 0x83, 0x1B,
94 0x00, 0x94, 0xFE, 0x06, 0xFF, 0x82, 0xBF, 0x00, 0xFE, 0x02, 0xFF, 0x85, 0x1F, 0xFD, 0xBF, 0x05,
95 0x00, 0xE9, 0x04, 0xFF, 0x82, 0x06, 0x40, 0xFE, 0x08, 0xFF, 0x81, 0x0B, 0xE0, 0x03, 0xFF, 0x84,
96 0xE1, 0xBF, 0x01, 0x94, 0xFE, 0x04, 0xFF, 0x81, 0x06, 0x90, 0x09, 0xFF, 0x82, 0xBF, 0x00, 0xFD,
97 0x02, 0xFF, 0x83, 0x1F, 0xFE, 0x01, 0xE5, 0x04, 0xFF, 0x82, 0xBF, 0x06, 0xA4, 0x0A, 0xFF, 0x81,
98 0x0B, 0xD0, 0x03, 0xFF, 0x82, 0xD1, 0x0B, 0xF9, 0x04, 0xFF, 0x82, 0xBF, 0x05, 0xE5, 0x0A, 0xFF,
99 0x82, 0xBF, 0x00, 0xFD, 0x02, 0xFF, 0x82, 0x2F, 0x7C, 0xF4, 0x04, 0xFF, 0x82, 0xBF, 0x05, 0xE5,
100 0x0B, 0xFF, 0x81, 0x07, 0x90, 0x03, 0xFF, 0x81, 0x42, 0x82, 0x04, 0xFF, 0x82, 0xBF, 0x05, 0xE9,
101 0x0B, 0xFF, 0x82, 0x7F, 0x00, 0xF8, 0x02, 0xFF, 0x82, 0xBF, 0x10, 0xF9, 0x04, 0xFF, 0x81, 0x05,
102 0xE9, 0x0C, 0xFF, 0x81, 0x06, 0x40, 0x03, 0xFF, 0x81, 0x1F, 0xD0, 0x04, 0xFF, 0x81, 0x06, 0xE0,
103 0x0C, 0xFF, 0x82, 0x2F, 0x00, 0xF4, 0x03, 0xFF, 0x81, 0x47, 0xFE, 0x03, 0xFF, 0x82, 0x06, 0x00,
104 0xE4, 0x0C, 0xFF, 0x82, 0x01, 0x00, 0xFE, 0x07, 0xFF, 0x83, 0x06, 0x90, 0x05, 0x90, 0x0B, 0xFF,
105 0x82, 0x1B, 0x00, 0xD0, 0x07, 0xFF, 0x85, 0x0B, 0x90, 0xFF, 0x16, 0x40, 0xFA, 0x09, 0xFF, 0x80,
106 0x7F, 0x02, 0x00, 0x80, 0xF9, 0x06, 0xFF, 0x81, 0x1B, 0x94, 0x02, 0xFF, 0x82, 0x5B, 0x00, 0xA5,
107 0x09, 0xFF, 0x82, 0x02, 0x00, 0x40, 0x06, 0xFF, 0x81, 0x1B, 0xD4, 0x03, 0xFF, 0x83, 0x6F, 0x01,
108 0x94, 0xFA, 0x07, 0xFF, 0x80, 0x1B, 0x02, 0x00, 0x80, 0xE0, 0x05, 0xFF, 0x81, 0x1B, 0x90, 0x04,
109 0xFF, 0x84, 0xBF, 0x16, 0x40, 0xA5, 0xFE, 0x05, 0xFF, 0x80, 0x6F, 0x03, 0x00, 0x80, 0xF8, 0x04,
110 0xFF, 0x81, 0x1B, 0x90, 0x06, 0xFF, 0x84, 0x6A, 0x01, 0x50, 0xA9, 0xFE, 0x03, 0xFF, 0x80, 0x6F,
111 0x04, 0x00, 0x80, 0xFE, 0x03, 0xFF, 0x81, 0x1B, 0x90, 0x07, 0xFF, 0x84, 0xAF, 0x16, 0x00, 0x50,
112 0x95, 0x02, 0xAA, 0x80, 0x56, 0x04, 0x00, 0x81, 0x40, 0xFE, 0x02, 0xFF, 0x81, 0x1B, 0x90, 0x09,
113 0xFF, 0x81, 0xAB, 0x05, 0x09, 0x00, 0x84, 0x40, 0xFA, 0xBF, 0x05, 0x90, 0x0B, 0xFF, 0x81, 0xAF,
114 0x55, 0x0B, 0x00, 0x80, 0x90, 0x0E, 0xFF, 0x80, 0xBF, 0x08, 0x00, 0x81, 0x40, 0xE5, 0x0F, 0xFF,
115 0x80, 0x02, 0x07, 0x00, 0x81, 0x90, 0xFE, 0x0F, 0xFF, 0x80, 0x07, 0x08, 0x00, 0x80, 0xF9, 0x0F,
116 0xFF, 0x80, 0x1F, 0x08, 0x00, 0x80, 0x40, 0x0F, 0xFF, 0x80, 0x7F, 0x09, 0x00, 0x80, 0xD0, 0x0F,
117 0xFF, 0x80, 0x01, 0x09, 0x00, 0x80, 0xF8, 0x0E, 0xFF, 0x80, 0x0B, 0x0A, 0x00, 0x80, 0xFE, 0x0D,
118 0xFF, 0x80, 0x2F, 0x0A, 0x00, 0x80, 0xD0, 0x0D, 0xFF, 0x81, 0xBF, 0x01, 0x0A, 0x00, 0x80, 0xF4,
119 0x0D, 0xFF, 0x80, 0x06, 0x0B, 0x00, 0x80, 0xFD, 0x0C, 0xFF, 0x80, 0x1F, 0x0B, 0x00, 0x80, 0x80,
120 0x0C, 0xFF, 0x80, 0xBF, 0x0C, 0x00, 0x80, 0xE4, 0x0C, 0xFF, 0x80, 0x02, 0x0C, 0x00, 0x80, 0xFD,
121 0x0B, 0xFF, 0x80, 0x1F, 0x0C, 0x00, 0x80, 0x80, 0x0B, 0xFF, 0x80, 0xBF, 0x0D, 0x00, 0x80, 0xE0,
122 0x0B, 0xFF, 0x80, 0x07, 0x0D, 0x00, 0x80, 0xFD, 0x0A, 0xFF, 0x80, 0x1F, 0x0D, 0x00, 0x80, 0x80,
123 0x0A, 0xFF, 0x80, 0xBF, 0x0E, 0x00, 0x80, 0xE0, 0x0A, 0xFF, 0x80, 0x07, 0x0E, 0x00, 0x80, 0xFD,
124 0x09, 0xFF, 0x80, 0x2F, 0x0E, 0x00, 0x80, 0x80, 0x0A, 0xFF, 0x80, 0x01, 0x0E, 0x00, 0x80, 0xE0,
125 0x09, 0xFF, 0x80, 0x0B, 0x0F, 0x00, 0x80, 0xFD, 0x08, 0xFF, 0x80, 0x7F, 0x0F, 0x00, 0x80, 0x80,
126 0x09, 0xFF, 0x80, 0x02, 0x0F, 0x00, 0x80, 0xF4, 0x08, 0xFF, 0x80, 0x1F, 0x10, 0x00, 0x80, 0xFE,
127 0x07, 0xFF, 0x80, 0xBF, 0x10, 0x00, 0x80, 0x90, 0x08, 0xFF, 0x80, 0x07, 0x10, 0x00, 0x80, 0xF4,
128 0x07, 0xFF, 0x80, 0x2F, 0x10, 0x00, 0x81, 0x40, 0xFE, 0x07, 0xFF, 0x80, 0x02, 0x10, 0x00, 0x80,
129 0xD0, 0x07, 0xFF, 0x80, 0x1F, 0x11, 0x00, 0x80, 0xF8, 0x06, 0xFF, 0x80, 0xBF, 0x11, 0x00, 0x80,
130 0x80, 0x07, 0xFF, 0x80, 0x07, 0x11, 0x00, 0x80, 0xF4, 0x06, 0xFF, 0x80, 0x3F, 0x12, 0x00, 0x80,
131 0xFE, 0x06, 0xFF, 0x80, 0x02, 0x11, 0x00, 0x80, 0xD0, 0x06, 0xFF, 0x80, 0x1F, 0x12, 0x00, 0x80,
132 0xFC, 0x05, 0xFF, 0x80, 0xBF, 0x12, 0x00, 0x80, 0x40, 0x06, 0xFF, 0x80, 0x07, 0x12, 0x00, 0x80,
133 0xF4, 0x05, 0xFF, 0x80, 0x7F, 0x13, 0x00, 0x80, 0xFE, 0x05, 0xFF, 0x80, 0x02, 0x12, 0x00, 0x80,
134 0xE0, 0x05, 0xFF, 0x80, 0x2F, 0x13, 0x00, 0x80, 0xFD, 0x05, 0xFF, 0x80, 0x01, 0x12, 0x00, 0x80,
135 0xD0, 0x05, 0xFF, 0x80, 0x1B, 0x13, 0x00, 0x80, 0xF8, 0x04, 0xFF, 0x80, 0xBF, 0x13, 0x00, 0x80,
136 0x80, 0x05, 0xFF, 0x80, 0x07, 0x13, 0x00, 0x80, 0xF8, 0x04, 0xFF, 0x80, 0x7F, 0x13, 0x00, 0x80,
137 0x40, 0x05, 0xFF, 0x80, 0x02, 0x13, 0x00, 0x80, 0xF4, 0x04, 0xFF, 0x80, 0x2F, 0x13, 0x00, 0x80,
138 0x40, 0x05, 0xFF, 0x80, 0x01, 0x13, 0x00, 0x80, 0xF8, 0x04, 0xFF, 0x80, 0x1B, 0x13, 0x00, 0x80,
139 0x80, 0x04, 0xFF, 0x80, 0xBF, 0x14, 0x00, 0x80, 0xF8, 0x04, 0xFF, 0x80, 0x07, 0x13, 0x00, 0x80,
140 0x80, 0x04, 0xFF, 0x80, 0x6F, 0x14, 0x00, 0x80, 0xF8, 0x04, 0xFF, 0x80, 0x02, 0x13, 0x00, 0x80,
141 0x80, 0x04, 0xFF, 0x80, 0x2F, 0x14, 0x00, 0x80, 0xFC, 0x04, 0xFF, 0x80, 0x01, 0x13, 0x00, 0x80,
142 0xD0, 0x04, 0xFF, 0x80, 0x0B, 0x14, 0x00, 0x80, 0xFD, 0x03, 0xFF, 0x80, 0x7F, 0x14, 0x00, 0x80,
143 0xD0, 0x04, 0xFF, 0x80, 0x02, 0x14, 0x00, 0x80, 0xFD, 0x03, 0xFF, 0x80, 0x1F, 0x14, 0x00, 0x80,
144 0xE0, 0x04, 0xFF, 0x15, 0x00, 0x80, 0xFE, 0x03, 0xFF, 0x80, 0x0B, 0x14, 0x00, 0x80, 0xF0, 0x03,
145 0xFF, 0x80, 0x7F, 0x15, 0x00, 0x04, 0xFF, 0x80, 0x02, 0x14, 0x00, 0x80, 0xF4, 0x03, 0xFF, 0x80,
146 0x1F, 0x14, 0x00, 0x80, 0x40, 0x03, 0xFF, 0x80, 0xBF, 0x15, 0x00, 0x80, 0xF8, 0x03, 0xFF, 0x80,
147 0x07, 0x14, 0x00, 0x80, 0x80, 0x03, 0xFF, 0x80, 0x1F, 0x15, 0x00, 0x80, 0xFC, 0x02, 0xFF, 0x81,
148 0xBF, 0x01, 0x14, 0x00, 0x80, 0xD0, 0x03, 0xFF, 0x80, 0x07, 0x15, 0x00, 0x80, 0xFD, 0x02, 0xFF,
149 0x80, 0x2F, 0x15, 0x00, 0x80, 0xE0, 0x02, 0xFF, 0x81, 0xBF, 0x01, 0x15, 0x00, 0x03, 0xFF, 0x80,
150 0x07, 0x15, 0x00, 0x80, 0xF4, 0x02, 0xFF, 0x80, 0x2F, 0x15, 0x00, 0x80, 0x40, 0x02, 0xFF, 0x80,
151 0xBF, 0x16, 0x00, 0x80, 0xF8, 0x02, 0xFF, 0x80, 0x07, 0x15, 0x00, 0x80, 0xD0, 0x02, 0xFF, 0x80,
152 0x1F, 0x16, 0x00, 0x82, 0xFD, 0xFF, 0xBF, 0x16, 0x00, 0x80, 0xE0, 0x02, 0xFF, 0x80, 0x02, 0x15,
153 0x00, 0x83, 0x40, 0xFE, 0xFF, 0x0B, 0x16, 0x00, 0x82, 0xF4, 0xFF, 0x6F, 0x16, 0x00, 0x83, 0x80,
154 0xFF, 0xBF, 0x01, 0x16, 0x00, 0x82, 0xFD, 0xFF, 0x06, 0x16, 0x00, 0x82, 0xE0, 0xFF, 0x0B, 0x16,
155 0x00, 0x82, 0x40, 0xFE, 0x2F, 0x17, 0x00, 0x81, 0xF8, 0xBF, 0x17, 0x00, 0x82, 0x90, 0xBF, 0x01,
156 0x17, 0x00, 0x81, 0xFE, 0x06, 0x17, 0x00, 0x81, 0xF4, 0x1B, 0x17, 0x00, 0x81, 0x80, 0x1B, 0x18,
157 0x00, 0x80, 0x2E, 0x18, 0x00, 0x80, 0x24, 0x18, 0x00, 0x80, 0x40, 0x7F, 0x00, 0x61, 0x00, 0x82,
158 0x40, 0x55, 0x01, 0x04, 0x00, 0x83, 0xA9, 0x01, 0x50, 0x1A, 0x0F, 0x00, 0x82, 0xFD, 0xBF, 0x16,
159 0x03, 0x00, 0x84, 0xF9, 0xBF, 0x40, 0xFF, 0x1B, 0x0E, 0x00, 0x83, 0xD0, 0xAA, 0xFA, 0x1B, 0x02,
160 0x00, 0x85, 0xE0, 0x56, 0x1E, 0xB9, 0xE5, 0x06, 0x0E, 0x00, 0x8A, 0x1D, 0x40, 0xE5, 0x0B, 0x00,
161 0x40, 0x1B, 0xD0, 0xE6, 0x02, 0x78, 0x0E, 0x00, 0x8B, 0xD0, 0x01, 0x00, 0xE5, 0x06, 0x00, 0x74,
162 0x00, 0x78, 0x1E, 0x40, 0x0B, 0x0E, 0x00, 0x80, 0x1D, 0x02, 0x00, 0x87, 0xB9, 0x00, 0x40, 0x07,
163 0x80, 0xA7, 0x01, 0xB4, 0x0E, 0x00, 0x8B, 0xD0, 0x01, 0x00, 0x40, 0x2E, 0x00, 0xB4, 0x00, 0x6D,
164 0x1E, 0x40, 0x0B, 0x0E, 0x00, 0x80, 0x1D, 0x02, 0x00, 0x87, 0x90, 0x07, 0x40, 0x2E, 0xE4, 0xD2,
165 0x07, 0x7D, 0x0E, 0x00, 0x81, 0xD0, 0x01, 0x02, 0x00, 0x87, 0xB4, 0x00, 0x90, 0xFF, 0x0B, 0xF8,
166 0xFF, 0x01, 0x0E, 0x00, 0x8A, 0x1D, 0x00, 0x01, 0x00, 0x1E, 0x00, 0xA4, 0x1A, 0x00, 0xA9, 0x06,
167 0x0E, 0x00, 0x85, 0xD0, 0x01, 0xA0, 0x01, 0xD0, 0x03, 0x14, 0x00, 0x84, 0x1D, 0x00, 0x6E, 0x00,
168 0x78, 0x14, 0x00, 0x85, 0xD0, 0x01, 0xE0, 0x0B, 0x40, 0x0B, 0x14, 0x00, 0x85, 0x1D, 0x00, 0xFE,
169 0x01, 0xE0, 0x01, 0x02, 0x55, 0x86, 0x41, 0x55, 0x15, 0x40, 0x06, 0x90, 0x5A, 0x02, 0x00, 0x82,
170 0x16, 0x50, 0x5A, 0x05, 0x00, 0x94, 0xD0, 0x01, 0xE0, 0x2E, 0x00, 0x2E, 0xE0, 0xFF, 0x2F, 0xF9,
171 0xFF, 0x06, 0xF8, 0x86, 0xFF, 0x1B, 0x00, 0xF8, 0x46, 0xFE, 0x1B, 0x05, 0x00, 0x94, 0x1D, 0x00,
172 0xDE, 0x07, 0xD0, 0x02, 0xAE, 0xEA, 0xD2, 0xAA, 0x7E, 0xE0, 0xBA, 0x7E, 0xE5, 0x07, 0xE0, 0xBB,
173 0xBE, 0xE5, 0x07, 0x04, 0x00, 0x95, 0xD0, 0x01, 0xE0, 0x79, 0x00, 0x3C, 0xE0, 0x01, 0x2D, 0x1D,
174 0x80, 0x87, 0x4F, 0xBE, 0x01, 0xB4, 0x41, 0x1F, 0xFE, 0x01, 0xF4, 0x01, 0x04, 0x00, 0x94, 0x1D,
175 0x00, 0x5E, 0x0B, 0x80, 0x07, 0x1E, 0xD0, 0xD2, 0x01, 0x78, 0x3E, 0x90, 0x06, 0x00, 0x1E, 0x7D,
176 0x80, 0x07, 0x00, 0x2D, 0x04, 0x00, 0x95, 0xD0, 0x01, 0xE0, 0xB5, 0x00, 0xB4, 0xE0, 0x01, 0x2D,
177 0x1D, 0x80, 0xFB, 0x01, 0x14, 0x00, 0xD0, 0xF6, 0x01, 0x14, 0x00, 0x90, 0x03, 0x04, 0x00, 0x94,
178 0x1D, 0x00, 0x1E, 0x0B, 0x40, 0x0B, 0x1E, 0xD0, 0xD2, 0x01, 0xB8, 0x0B, 0x00, 0x14, 0x00, 0xA9,
179 0x1F, 0x00, 0x14, 0x00, 0x78, 0x04, 0x00, 0x95, 0xD0, 0x01, 0xE0, 0xB1, 0x01, 0xB0, 0xE0, 0x01,
180 0x2D, 0x1D, 0x80, 0xE7, 0x01, 0x90, 0x06, 0x80, 0xE7, 0x02, 0x90, 0x0B, 0x80, 0x07, 0x04, 0x00,
181 0x94, 0x1D, 0x00, 0x1E, 0x1A, 0x00, 0x1F, 0x1E, 0xD0, 0xD2, 0x01, 0x78, 0x2D, 0x40, 0xFB, 0x01,
182 0x78, 0x2D, 0x40, 0xEE, 0x01, 0x78, 0x04, 0x00, 0x95, 0xD0, 0x01, 0xE0, 0xE1, 0x01, 0xE0, 0xE1,
183 0x01, 0x2D, 0x1D, 0x80, 0xD7, 0x02, 0x74, 0x1E, 0x80, 0xC7, 0x03, 0xB4, 0x2D, 0x80, 0x07, 0x04,
184 0x00, 0x81, 0x1D, 0x00, 0x02, 0x1E, 0x80, 0x00, 0x02, 0x1E, 0x8D, 0xD0, 0xD2, 0x01, 0x78, 0x2D,
185 0x40, 0xE7, 0x01, 0x78, 0x3C, 0x40, 0xDB, 0x02, 0x78, 0x04, 0x00, 0x95, 0xD0, 0x01, 0xE0, 0xE1,
186 0x01, 0xE0, 0xE1, 0x01, 0x2D, 0x1D, 0x80, 0xD7, 0x02, 0x74, 0x1E, 0x80, 0xC7, 0x03, 0xB4, 0x2D,
187 0x80, 0x07, 0x04, 0x00, 0x81, 0x1D, 0x00, 0x02, 0x1E, 0x80, 0x00, 0x02, 0x1E, 0x8D, 0xD0, 0xD2,
188 0x01, 0x78, 0x2D, 0x40, 0xE7, 0x01, 0x78, 0x3C, 0x40, 0xDB, 0x02, 0x78, 0x04, 0x00, 0x95, 0xD0,
189 0x01, 0xE0, 0xD1, 0x01, 0xD0, 0xE2, 0x01, 0x2D, 0x1D, 0x80, 0xD7, 0x02, 0x74, 0x1E, 0x80, 0xC7,
190 0x03, 0xB4, 0x2D, 0x80, 0x07, 0x04, 0x00, 0x94, 0x1D, 0x00, 0x1E, 0x1D, 0x00, 0x2D, 0x1E, 0xD0,
191 0xD2, 0x01, 0x78, 0x2D, 0x40, 0xE7, 0x01, 0x78, 0x3C, 0x40, 0xDB, 0x02, 0x78, 0x04, 0x00, 0x95,
192 0xD0, 0x01, 0xE0, 0xD1, 0x01, 0xD0, 0xE2, 0x01, 0x2D, 0x1D, 0x80, 0xD7, 0x02, 0x74, 0x1E, 0x80,
193 0xC7, 0x03, 0xB4, 0x2D, 0x80, 0x07, 0x04, 0x00, 0x94, 0x1D, 0x00, 0x1E, 0x1D, 0x00, 0x2D, 0x1E,
194 0xD0, 0xD2, 0x01, 0x78, 0x2D, 0x40, 0xE7, 0x01, 0x78, 0x3C, 0x40, 0xDB, 0x02, 0x78, 0x04, 0x00,
195 0x95, 0xD0, 0x01, 0xE0, 0xD1, 0x01, 0xD0, 0xE2, 0x01, 0x2D, 0x1D, 0x80, 0xD7, 0x02, 0x74, 0x1E,
196 0x80, 0xC7, 0x03, 0xB4, 0x2D, 0x80, 0x07, 0x04, 0x00, 0x94, 0x1D, 0x00, 0x1E, 0x1D, 0x00, 0x2D,
197 0x1E, 0xD0, 0xD2, 0x01, 0x78, 0x2D, 0x40, 0xE7, 0x01, 0x78, 0x3C, 0x40, 0xDB, 0x02, 0x78, 0x04,
198 0x00, 0x95, 0xD0, 0x01, 0xE0, 0xD1, 0x01, 0xD0, 0xE2, 0x01, 0x2D, 0x1D, 0x80, 0xD7, 0x02, 0x74,
199 0x1E, 0x80, 0xC7, 0x03, 0xB4, 0x2D, 0x80, 0x07, 0x04, 0x00, 0x94, 0x1D, 0x00, 0x1E, 0x1D, 0x00,
200 0x1D, 0x1E, 0xD0, 0xD2, 0x01, 0x78, 0x2D, 0x40, 0xE7, 0x01, 0x78, 0x3C, 0x40, 0xDB, 0x02, 0x78,
201 0x04, 0x00, 0x95, 0xD0, 0x01, 0xE0, 0xD1, 0x01, 0xE0, 0xE1, 0x01, 0x2D, 0x1D, 0x80, 0xD7, 0x02,
202 0x74, 0x1E, 0x80, 0xC7, 0x03, 0xB4, 0x2D, 0x80, 0x07, 0x04, 0x00, 0x81, 0x1D, 0x00, 0x02, 0x1E,
203 0x80, 0x00, 0x02, 0x1E, 0x8D, 0xD0, 0xD2, 0x01, 0x78, 0x2D, 0x40, 0xE7, 0x01, 0x78, 0x3C, 0x40,
204 0xDB, 0x02, 0x78, 0x04, 0x00, 0x95, 0xD0, 0x01, 0xE0, 0xE1, 0x01, 0xE0, 0xE1, 0x01, 0x2D, 0x1D,
205 0x80, 0xD7, 0x02, 0x74, 0x1E, 0x80, 0xC7, 0x03, 0xB4, 0x2D, 0x80, 0x07, 0x04, 0x00, 0x81, 0x1D,
206 0x00, 0x02, 0x1E, 0x80, 0x00, 0x02, 0x1E, 0x8D, 0xD0, 0xD2, 0x01, 0x78, 0x2D, 0x40, 0xE7, 0x01,
207 0x78, 0x3C, 0x40, 0xDB, 0x02, 0x78, 0x04, 0x00, 0x95, 0xD0, 0x01, 0xE0, 0xE1, 0x01, 0xF0, 0xE1,
208 0x01, 0x2D, 0x1D, 0x80, 0xD7, 0x02, 0x74, 0x1E, 0x80, 0xC7, 0x03, 0xB4, 0x2D, 0x80, 0x07, 0x04,
209 0x00, 0x94, 0x1D, 0x00, 0x1E, 0x1A, 0x00, 0x0B, 0x1E, 0xD0, 0xD2, 0x01, 0x78, 0x2D, 0x40, 0xE7,
210 0x01, 0x78, 0x3C, 0x40, 0xDB, 0x02, 0x78, 0x04, 0x00, 0x95, 0xD0, 0x01, 0xE0, 0xA1, 0x01, 0xB4,
211 0xE0, 0x01, 0x2D, 0x1D, 0x80, 0xD7, 0x02, 0x74, 0x1E, 0x80, 0xC7, 0x03, 0xB4, 0x2D, 0x80, 0x07,
212 0x04, 0x00, 0x94, 0x1D, 0x00, 0x1E, 0x0B, 0x40, 0x0B, 0x1E, 0xD0, 0xD2, 0x01, 0x78, 0x2D, 0x40,
213 0xE7, 0x01, 0x78, 0x3C, 0x40, 0xDB, 0x02, 0x78, 0x04, 0x00, 0x95, 0xD0, 0x01, 0xE0, 0xB5, 0x00,
214 0x78, 0xE0, 0x01, 0x2D, 0x1D, 0x80, 0xD7, 0x02, 0x74, 0x1E, 0x80, 0xC7, 0x03, 0xB4, 0x2D, 0x80,
215 0x07, 0x04, 0x00, 0x94, 0x1D, 0x00, 0x5E, 0x0B, 0x80, 0x07, 0x1E, 0xD0, 0xD2, 0x01, 0x78, 0x2D,
216 0x40, 0xE7, 0x01, 0x78, 0x3C, 0x40, 0xDB, 0x02, 0x78, 0x04, 0x00, 0x95, 0xD0, 0x01, 0xE0, 0x79,
217 0x00, 0x3C, 0xE0, 0x01, 0x2D, 0x1D, 0x80, 0xD7, 0x02, 0x74, 0x1E, 0x80, 0xC7, 0x03, 0xB4, 0x2D,
218 0x80, 0x07, 0x04, 0x00, 0x94, 0x1D, 0x00, 0xDE, 0x02, 0xD0, 0x02, 0x1E, 0xD0, 0xD2, 0x01, 0x78,
219 0x2D, 0x40, 0xE7, 0x01, 0x78, 0x3C, 0x40, 0xDB, 0x02, 0x78, 0x04, 0x00, 0x95, 0xD0, 0x01, 0xE0,
220 0x2E, 0x00, 0x1E, 0xE0, 0x01, 0x2D, 0x1D, 0x80, 0xD7, 0x02, 0x74, 0x1E, 0x80, 0xC7, 0x03, 0xB4,
221 0x2D, 0x80, 0x07, 0x04, 0x00, 0x94, 0x1D, 0x00, 0xFE, 0x01, 0xE0, 0x00, 0x1E, 0xD0, 0xD2, 0x01,
222 0x78, 0x2D, 0x40, 0xE7, 0x01, 0x78, 0x3C, 0x40, 0xDB, 0x02, 0x78, 0x04, 0x00, 0x95, 0xD0, 0x01,
223 0xE0, 0x07, 0x40, 0x0B, 0xE0, 0x01, 0x2D, 0x1D, 0x80, 0xD7, 0x02, 0x74, 0x1E, 0x80, 0xC7, 0x03,
224 0xB4, 0x2D, 0x80, 0x07, 0x04, 0x00, 0x94, 0x1D, 0x00, 0x1E, 0x00, 0x78, 0x00, 0x1E, 0xD0, 0xD2,
225 0x01, 0x78, 0x2D, 0x40, 0xE7, 0x01, 0x78, 0x3C, 0x40, 0xDB, 0x02, 0x78, 0x04, 0x00, 0x95, 0xD0,
226 0x01, 0x60, 0x00, 0xD0, 0x02, 0xE0, 0x01, 0x2D, 0x1D, 0x80, 0xD7, 0x02, 0x74, 0x1E, 0x80, 0xC7,
227 0x03, 0xB4, 0x2D, 0x80, 0x07, 0x04, 0x00, 0x80, 0x1D, 0x03, 0x00, 0x90, 0x1E, 0x00, 0x1E, 0xD0,
228 0xD2, 0x01, 0x78, 0x2D, 0x40, 0xE7, 0x01, 0x78, 0x3C, 0x40, 0xDB, 0x02, 0x78, 0x04, 0x00, 0x81,
229 0xD0, 0x01, 0x02, 0x00, 0x91, 0xB4, 0x00, 0xE0, 0x01, 0x2D, 0x1D, 0x80, 0xD7, 0x02, 0x74, 0x1E,
230 0x80, 0xC7, 0x03, 0xB4, 0x2D, 0x80, 0x07, 0x04, 0x00, 0x80, 0x1D, 0x02, 0x00, 0x91, 0xD0, 0x07,
231 0x00, 0x1E, 0xD0, 0xD2, 0x01, 0x78, 0x2D, 0x40, 0xE7, 0x01, 0x78, 0x3C, 0x40, 0xDB, 0x02, 0x78,
232 0x04, 0x00, 0x95, 0xD0, 0x01, 0x00, 0x40, 0x1F, 0x00, 0xE0, 0x01, 0x2D, 0x1D, 0x80, 0xD7, 0x02,
233 0x74, 0x1E, 0x80, 0xC7, 0x03, 0xB4, 0x2D, 0x80, 0x07, 0x04, 0x00, 0x80, 0x1D, 0x02, 0x00, 0x80,
234 0x7D, 0x02, 0x00, 0x8E, 0x1E, 0xD0, 0xD2, 0x01, 0x78, 0x2D, 0x40, 0xE7, 0x01, 0x78, 0x3C, 0x40,
235 0xDB, 0x02, 0x78, 0x04, 0x00, 0x95, 0xD0, 0x01, 0x40, 0xF9, 0x01, 0x00, 0xE0, 0x01, 0x2D, 0x1D,
236 0x80, 0xD7, 0x02, 0x74, 0x1E, 0x80, 0xC7, 0x03, 0xB4, 0x2D, 0x80, 0x07, 0x04, 0x00, 0x94, 0x6D,
237 0x95, 0xFA, 0x06, 0x00, 0x40, 0x1A, 0xD0, 0xD2, 0x56, 0x79, 0x6D, 0x95, 0xE7, 0x56, 0x79, 0x7C,
238 0x95, 0xDB, 0x56, 0x79, 0x04, 0x00, 0x83, 0xD0, 0xFF, 0xBF, 0x06, 0x02, 0x00, 0x8F, 0xB8, 0x00,
239 0x2D, 0xFD, 0xFF, 0xD7, 0xFF, 0x7F, 0xFE, 0xFF, 0xC7, 0xFF, 0xBF, 0xFD, 0xFF, 0x07, 0x04, 0x00,
240 0x02, 0x55, 0x80, 0x05, 0x02, 0x00, 0x8F, 0xE4, 0x07, 0xD0, 0x52, 0x55, 0x15, 0x54, 0x55, 0x51,
241 0x55, 0x15, 0x54, 0x55, 0x45, 0x55, 0x15, 0x09, 0x00, 0x83, 0x40, 0x1B, 0x00, 0x2D, 0x16, 0x00,
242 0x83, 0xB4, 0x00, 0xE0, 0x01, 0x15, 0x00, 0x83, 0x40, 0x0B, 0x40, 0x0B, 0x16, 0x00, 0x82, 0xB4,
243 0x00, 0x7D, 0x16, 0x00, 0x83, 0x40, 0x0B, 0xF5, 0x01, 0x16, 0x00, 0x82, 0xB4, 0xE5, 0x07, 0x16,
244 0x00, 0x82, 0x40, 0xFF, 0x1B, 0x17, 0x00, 0x81, 0xA4, 0x16, 0x5D, 0x00,
245};
246// clang-format on
diff --git a/keyboards/tzarc/djinn/graphics/djinn.qgf.h b/keyboards/tzarc/djinn/graphics/djinn.qgf.h
new file mode 100644
index 0000000000..59711daffd
--- /dev/null
+++ b/keyboards/tzarc/djinn/graphics/djinn.qgf.h
@@ -0,0 +1,11 @@
1// Copyright 2022 QMK -- generated source code only, image retains original copyright
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4// This file was auto-generated by `qmk painter-convert-graphics -i djinn.png -f mono4`
5
6#pragma once
7
8#include <qp.h>
9
10extern const uint32_t gfx_djinn_length;
11extern const uint8_t gfx_djinn[3724];
diff --git a/keyboards/tzarc/djinn/graphics/lock-caps-OFF.qgf.c b/keyboards/tzarc/djinn/graphics/lock-caps-OFF.qgf.c
new file mode 100644
index 0000000000..5aef043e3a
--- /dev/null
+++ b/keyboards/tzarc/djinn/graphics/lock-caps-OFF.qgf.c
@@ -0,0 +1,31 @@
1// Copyright 2022 QMK -- generated source code only, image retains original copyright
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4// This file was auto-generated by `qmk painter-convert-graphics -i lock-caps-OFF.png -f mono4`
5
6#include <qp.h>
7
8const uint32_t gfx_lock_caps_OFF_length = 288;
9
10// clang-format off
11const uint8_t gfx_lock_caps_OFF[288] = {
12 0x00, 0xFF, 0x12, 0x00, 0x00, 0x51, 0x47, 0x46, 0x01, 0x20, 0x01, 0x00, 0x00, 0xDF, 0xFE, 0xFF,
13 0xFF, 0x20, 0x00, 0x20, 0x00, 0x01, 0x00, 0x01, 0xFE, 0x04, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
14 0x02, 0xFD, 0x06, 0x00, 0x00, 0x01, 0x00, 0x01, 0xFF, 0xE8, 0x03, 0x05, 0xFA, 0xF0, 0x00, 0x00,
15 0x08, 0x00, 0x80, 0xFC, 0x04, 0xFF, 0x80, 0x0F, 0x02, 0x00, 0x80, 0xFC, 0x04, 0xFF, 0x80, 0x3F,
16 0x02, 0x00, 0x80, 0x3C, 0x04, 0x00, 0x80, 0xFC, 0x02, 0x00, 0x80, 0x3C, 0x04, 0x00, 0x83, 0xF0,
17 0x03, 0x00, 0x3C, 0x04, 0x00, 0x83, 0xC0, 0x0F, 0x00, 0x3C, 0x05, 0x00, 0x82, 0x3F, 0x00, 0x3C,
18 0x02, 0x00, 0x85, 0xF0, 0x0F, 0x00, 0xFC, 0x00, 0x3C, 0x02, 0x00, 0x85, 0xF0, 0x0F, 0x00, 0xF0,
19 0x03, 0x3C, 0x02, 0x00, 0x85, 0xFC, 0x0F, 0x00, 0xC0, 0x0F, 0x3C, 0x02, 0x00, 0x81, 0xFC, 0x3F,
20 0x02, 0x00, 0x81, 0x3F, 0x3C, 0x02, 0x00, 0x81, 0xFC, 0x3F, 0x02, 0x00, 0x02, 0x3C, 0x02, 0x00,
21 0x81, 0xFC, 0x3F, 0x02, 0x00, 0x02, 0x3C, 0x02, 0x00, 0x81, 0xFC, 0x3F, 0x02, 0x00, 0x02, 0x3C,
22 0x02, 0x00, 0x02, 0x3F, 0x02, 0x00, 0x02, 0x3C, 0x02, 0x00, 0x81, 0x3F, 0xFC, 0x02, 0x00, 0x02,
23 0x3C, 0x02, 0x00, 0x81, 0x3F, 0xFC, 0x02, 0x00, 0x02, 0x3C, 0x02, 0x00, 0x81, 0x3F, 0xFC, 0x02,
24 0x00, 0x02, 0x3C, 0x81, 0x00, 0xC0, 0x02, 0xFF, 0x02, 0x00, 0x02, 0x3C, 0x81, 0x00, 0xC0, 0x02,
25 0xFF, 0x81, 0x03, 0x00, 0x02, 0x3C, 0x81, 0x00, 0xC0, 0x02, 0xFF, 0x81, 0x03, 0x00, 0x02, 0x3C,
26 0x85, 0x00, 0xC0, 0x0F, 0xF0, 0x03, 0x00, 0x02, 0x3C, 0x85, 0x00, 0xF0, 0x0F, 0xF0, 0x03, 0x00,
27 0x02, 0x3C, 0x85, 0x00, 0xF0, 0x0F, 0xF0, 0x0F, 0x00, 0x02, 0x3C, 0x85, 0x00, 0xF0, 0x03, 0xF0,
28 0x0F, 0x00, 0x02, 0x3C, 0x06, 0x00, 0x02, 0x3C, 0x06, 0x00, 0x02, 0x3C, 0x06, 0x00, 0x02, 0x3C,
29 0x06, 0x00, 0x81, 0x3C, 0xFC, 0x06, 0xFF, 0x81, 0x3F, 0xFC, 0x06, 0xFF, 0x80, 0x3F, 0x08, 0x00,
30};
31// clang-format on
diff --git a/keyboards/tzarc/djinn/graphics/lock-caps-OFF.qgf.h b/keyboards/tzarc/djinn/graphics/lock-caps-OFF.qgf.h
new file mode 100644
index 0000000000..9d79762833
--- /dev/null
+++ b/keyboards/tzarc/djinn/graphics/lock-caps-OFF.qgf.h
@@ -0,0 +1,11 @@
1// Copyright 2022 QMK -- generated source code only, image retains original copyright
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4// This file was auto-generated by `qmk painter-convert-graphics -i lock-caps-OFF.png -f mono4`
5
6#pragma once
7
8#include <qp.h>
9
10extern const uint32_t gfx_lock_caps_OFF_length;
11extern const uint8_t gfx_lock_caps_OFF[288];
diff --git a/keyboards/tzarc/djinn/graphics/lock-caps-ON.qgf.c b/keyboards/tzarc/djinn/graphics/lock-caps-ON.qgf.c
new file mode 100644
index 0000000000..9da36cb446
--- /dev/null
+++ b/keyboards/tzarc/djinn/graphics/lock-caps-ON.qgf.c
@@ -0,0 +1,32 @@
1// Copyright 2022 QMK -- generated source code only, image retains original copyright
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4// This file was auto-generated by `qmk painter-convert-graphics -i lock-caps-ON.png -f mono4`
5
6#include <qp.h>
7
8const uint32_t gfx_lock_caps_ON_length = 291;
9
10// clang-format off
11const uint8_t gfx_lock_caps_ON[291] = {
12 0x00, 0xFF, 0x12, 0x00, 0x00, 0x51, 0x47, 0x46, 0x01, 0x23, 0x01, 0x00, 0x00, 0xDC, 0xFE, 0xFF,
13 0xFF, 0x20, 0x00, 0x20, 0x00, 0x01, 0x00, 0x01, 0xFE, 0x04, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
14 0x02, 0xFD, 0x06, 0x00, 0x00, 0x01, 0x00, 0x01, 0xFF, 0xE8, 0x03, 0x05, 0xFA, 0xF3, 0x00, 0x00,
15 0x08, 0x00, 0x80, 0xFC, 0x04, 0xFF, 0x80, 0x0F, 0x02, 0x00, 0x80, 0xFC, 0x04, 0xFF, 0x80, 0x3F,
16 0x02, 0x00, 0x80, 0xFC, 0x05, 0xFF, 0x02, 0x00, 0x80, 0xFC, 0x05, 0xFF, 0x82, 0x03, 0x00, 0xFC,
17 0x05, 0xFF, 0x82, 0x0F, 0x00, 0xFC, 0x05, 0xFF, 0x82, 0x3F, 0x00, 0xFC, 0x02, 0xFF, 0x81, 0x0F,
18 0xF0, 0x02, 0xFF, 0x81, 0x00, 0xFC, 0x02, 0xFF, 0x81, 0x0F, 0xF0, 0x02, 0xFF, 0x81, 0x03, 0xFC,
19 0x02, 0xFF, 0x81, 0x03, 0xF0, 0x02, 0xFF, 0x81, 0x0F, 0xFC, 0x02, 0xFF, 0x81, 0x03, 0xC0, 0x02,
20 0xFF, 0x81, 0x3F, 0xFC, 0x02, 0xFF, 0x81, 0x03, 0xC0, 0x02, 0xFF, 0x81, 0x3F, 0xFC, 0x02, 0xFF,
21 0x81, 0x03, 0xC0, 0x02, 0xFF, 0x81, 0x3F, 0xFC, 0x02, 0xFF, 0x81, 0x03, 0xC0, 0x02, 0xFF, 0x81,
22 0x3F, 0xFC, 0x02, 0xFF, 0x02, 0xC0, 0x02, 0xFF, 0x81, 0x3F, 0xFC, 0x02, 0xFF, 0x81, 0xC0, 0x03,
23 0x02, 0xFF, 0x81, 0x3F, 0xFC, 0x02, 0xFF, 0x81, 0xC0, 0x03, 0x02, 0xFF, 0x81, 0x3F, 0xFC, 0x02,
24 0xFF, 0x81, 0xC0, 0x03, 0x02, 0xFF, 0x83, 0x3F, 0xFC, 0xFF, 0x3F, 0x02, 0x00, 0x02, 0xFF, 0x83,
25 0x3F, 0xFC, 0xFF, 0x3F, 0x02, 0x00, 0x85, 0xFC, 0xFF, 0x3F, 0xFC, 0xFF, 0x3F, 0x02, 0x00, 0xA3,
26 0xFC, 0xFF, 0x3F, 0xFC, 0xFF, 0x3F, 0xF0, 0x0F, 0xFC, 0xFF, 0x3F, 0xFC, 0xFF, 0x0F, 0xF0, 0x0F,
27 0xFC, 0xFF, 0x3F, 0xFC, 0xFF, 0x0F, 0xF0, 0x0F, 0xF0, 0xFF, 0x3F, 0xFC, 0xFF, 0x0F, 0xFC, 0x0F,
28 0xF0, 0xFF, 0x3F, 0xFC, 0x06, 0xFF, 0x81, 0x3F, 0xFC, 0x06, 0xFF, 0x81, 0x3F, 0xFC, 0x06, 0xFF,
29 0x81, 0x3F, 0xFC, 0x06, 0xFF, 0x81, 0x3F, 0xFC, 0x06, 0xFF, 0x81, 0x3F, 0xFC, 0x06, 0xFF, 0x80,
30 0x3F, 0x08, 0x00,
31};
32// clang-format on
diff --git a/keyboards/tzarc/djinn/graphics/lock-caps-ON.qgf.h b/keyboards/tzarc/djinn/graphics/lock-caps-ON.qgf.h
new file mode 100644
index 0000000000..a7d60a6195
--- /dev/null
+++ b/keyboards/tzarc/djinn/graphics/lock-caps-ON.qgf.h
@@ -0,0 +1,11 @@
1// Copyright 2022 QMK -- generated source code only, image retains original copyright
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4// This file was auto-generated by `qmk painter-convert-graphics -i lock-caps-ON.png -f mono4`
5
6#pragma once
7
8#include <qp.h>
9
10extern const uint32_t gfx_lock_caps_ON_length;
11extern const uint8_t gfx_lock_caps_ON[291];
diff --git a/keyboards/tzarc/djinn/graphics/lock-num-OFF.qgf.c b/keyboards/tzarc/djinn/graphics/lock-num-OFF.qgf.c
new file mode 100644
index 0000000000..2dd7dbef73
--- /dev/null
+++ b/keyboards/tzarc/djinn/graphics/lock-num-OFF.qgf.c
@@ -0,0 +1,31 @@
1// Copyright 2022 QMK -- generated source code only, image retains original copyright
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4// This file was auto-generated by `qmk painter-convert-graphics -i lock-num-OFF.png -f mono4`
5
6#include <qp.h>
7
8const uint32_t gfx_lock_num_OFF_length = 286;
9
10// clang-format off
11const uint8_t gfx_lock_num_OFF[286] = {
12 0x00, 0xFF, 0x12, 0x00, 0x00, 0x51, 0x47, 0x46, 0x01, 0x1E, 0x01, 0x00, 0x00, 0xE1, 0xFE, 0xFF,
13 0xFF, 0x20, 0x00, 0x20, 0x00, 0x01, 0x00, 0x01, 0xFE, 0x04, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
14 0x02, 0xFD, 0x06, 0x00, 0x00, 0x01, 0x00, 0x01, 0xFF, 0xE8, 0x03, 0x05, 0xFA, 0xEE, 0x00, 0x00,
15 0x08, 0x00, 0x80, 0xFC, 0x04, 0xFF, 0x80, 0x0F, 0x02, 0x00, 0x80, 0xFC, 0x04, 0xFF, 0x80, 0x3F,
16 0x02, 0x00, 0x80, 0x3C, 0x04, 0x00, 0x80, 0xFC, 0x02, 0x00, 0x80, 0x3C, 0x04, 0x00, 0x83, 0xF0,
17 0x03, 0x00, 0x3C, 0x04, 0x00, 0x83, 0xC0, 0x0F, 0x00, 0x3C, 0x05, 0x00, 0x82, 0x3F, 0x00, 0x3C,
18 0x02, 0x00, 0x85, 0xF0, 0x0F, 0x00, 0xFC, 0x00, 0x3C, 0x02, 0x00, 0x85, 0xFC, 0x0F, 0x00, 0xF0,
19 0x03, 0x3C, 0x02, 0x00, 0x89, 0xFF, 0x0F, 0x00, 0xC0, 0x0F, 0x3C, 0x00, 0xC0, 0xFF, 0x0F, 0x02,
20 0x00, 0x81, 0x3F, 0x3C, 0x02, 0x00, 0x81, 0xCF, 0x0F, 0x02, 0x00, 0x02, 0x3C, 0x02, 0x00, 0x81,
21 0xC0, 0x0F, 0x02, 0x00, 0x02, 0x3C, 0x02, 0x00, 0x81, 0xC0, 0x0F, 0x02, 0x00, 0x02, 0x3C, 0x02,
22 0x00, 0x81, 0xC0, 0x0F, 0x02, 0x00, 0x02, 0x3C, 0x02, 0x00, 0x81, 0xC0, 0x0F, 0x02, 0x00, 0x02,
23 0x3C, 0x02, 0x00, 0x81, 0xC0, 0x0F, 0x02, 0x00, 0x02, 0x3C, 0x02, 0x00, 0x81, 0xC0, 0x0F, 0x02,
24 0x00, 0x02, 0x3C, 0x02, 0x00, 0x81, 0xC0, 0x0F, 0x02, 0x00, 0x02, 0x3C, 0x02, 0x00, 0x81, 0xC0,
25 0x0F, 0x02, 0x00, 0x02, 0x3C, 0x02, 0x00, 0x81, 0xC0, 0x0F, 0x02, 0x00, 0x02, 0x3C, 0x02, 0x00,
26 0x81, 0xC0, 0x0F, 0x02, 0x00, 0x02, 0x3C, 0x02, 0x00, 0x81, 0xC0, 0x0F, 0x02, 0x00, 0x02, 0x3C,
27 0x02, 0x00, 0x81, 0xC0, 0x0F, 0x02, 0x00, 0x02, 0x3C, 0x02, 0x00, 0x81, 0xC0, 0x0F, 0x02, 0x00,
28 0x02, 0x3C, 0x06, 0x00, 0x02, 0x3C, 0x06, 0x00, 0x02, 0x3C, 0x06, 0x00, 0x02, 0x3C, 0x06, 0x00,
29 0x81, 0x3C, 0xFC, 0x06, 0xFF, 0x81, 0x3F, 0xFC, 0x06, 0xFF, 0x80, 0x3F, 0x08, 0x00,
30};
31// clang-format on
diff --git a/keyboards/tzarc/djinn/graphics/lock-num-OFF.qgf.h b/keyboards/tzarc/djinn/graphics/lock-num-OFF.qgf.h
new file mode 100644
index 0000000000..c0b24bffbd
--- /dev/null
+++ b/keyboards/tzarc/djinn/graphics/lock-num-OFF.qgf.h
@@ -0,0 +1,11 @@
1// Copyright 2022 QMK -- generated source code only, image retains original copyright
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4// This file was auto-generated by `qmk painter-convert-graphics -i lock-num-OFF.png -f mono4`
5
6#pragma once
7
8#include <qp.h>
9
10extern const uint32_t gfx_lock_num_OFF_length;
11extern const uint8_t gfx_lock_num_OFF[286];
diff --git a/keyboards/tzarc/djinn/graphics/lock-num-ON.qgf.c b/keyboards/tzarc/djinn/graphics/lock-num-ON.qgf.c
new file mode 100644
index 0000000000..803dc6b19a
--- /dev/null
+++ b/keyboards/tzarc/djinn/graphics/lock-num-ON.qgf.c
@@ -0,0 +1,32 @@
1// Copyright 2022 QMK -- generated source code only, image retains original copyright
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4// This file was auto-generated by `qmk painter-convert-graphics -i lock-num-ON.png -f mono4`
5
6#include <qp.h>
7
8const uint32_t gfx_lock_num_ON_length = 302;
9
10// clang-format off
11const uint8_t gfx_lock_num_ON[302] = {
12 0x00, 0xFF, 0x12, 0x00, 0x00, 0x51, 0x47, 0x46, 0x01, 0x2E, 0x01, 0x00, 0x00, 0xD1, 0xFE, 0xFF,
13 0xFF, 0x20, 0x00, 0x20, 0x00, 0x01, 0x00, 0x01, 0xFE, 0x04, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
14 0x02, 0xFD, 0x06, 0x00, 0x00, 0x01, 0x00, 0x01, 0xFF, 0xE8, 0x03, 0x05, 0xFA, 0xFE, 0x00, 0x00,
15 0x08, 0x00, 0x80, 0xFC, 0x04, 0xFF, 0x80, 0x0F, 0x02, 0x00, 0x80, 0xFC, 0x04, 0xFF, 0x80, 0x3F,
16 0x02, 0x00, 0x80, 0xFC, 0x05, 0xFF, 0x02, 0x00, 0x80, 0xFC, 0x05, 0xFF, 0x82, 0x03, 0x00, 0xFC,
17 0x05, 0xFF, 0x82, 0x0F, 0x00, 0xFC, 0x05, 0xFF, 0x82, 0x3F, 0x00, 0xFC, 0x02, 0xFF, 0x81, 0x0F,
18 0xF0, 0x02, 0xFF, 0x81, 0x00, 0xFC, 0x02, 0xFF, 0x81, 0x03, 0xF0, 0x02, 0xFF, 0x81, 0x03, 0xFC,
19 0x02, 0xFF, 0x81, 0x00, 0xF0, 0x02, 0xFF, 0x85, 0x0F, 0xFC, 0xFF, 0x3F, 0x00, 0xF0, 0x02, 0xFF,
20 0x81, 0x3F, 0xFC, 0x02, 0xFF, 0x81, 0x30, 0xF0, 0x02, 0xFF, 0x81, 0x3F, 0xFC, 0x02, 0xFF, 0x81,
21 0x3F, 0xF0, 0x02, 0xFF, 0x81, 0x3F, 0xFC, 0x02, 0xFF, 0x81, 0x3F, 0xF0, 0x02, 0xFF, 0x81, 0x3F,
22 0xFC, 0x02, 0xFF, 0x81, 0x3F, 0xF0, 0x02, 0xFF, 0x81, 0x3F, 0xFC, 0x02, 0xFF, 0x81, 0x3F, 0xF0,
23 0x02, 0xFF, 0x81, 0x3F, 0xFC, 0x02, 0xFF, 0x81, 0x3F, 0xF0, 0x02, 0xFF, 0x81, 0x3F, 0xFC, 0x02,
24 0xFF, 0x81, 0x3F, 0xF0, 0x02, 0xFF, 0x81, 0x3F, 0xFC, 0x02, 0xFF, 0x81, 0x3F, 0xF0, 0x02, 0xFF,
25 0x81, 0x3F, 0xFC, 0x02, 0xFF, 0x81, 0x3F, 0xF0, 0x02, 0xFF, 0x81, 0x3F, 0xFC, 0x02, 0xFF, 0x81,
26 0x3F, 0xF0, 0x02, 0xFF, 0x81, 0x3F, 0xFC, 0x02, 0xFF, 0x81, 0x3F, 0xF0, 0x02, 0xFF, 0x81, 0x3F,
27 0xFC, 0x02, 0xFF, 0x81, 0x3F, 0xF0, 0x02, 0xFF, 0x81, 0x3F, 0xFC, 0x02, 0xFF, 0x81, 0x3F, 0xF0,
28 0x02, 0xFF, 0x81, 0x3F, 0xFC, 0x02, 0xFF, 0x81, 0x3F, 0xF0, 0x02, 0xFF, 0x81, 0x3F, 0xFC, 0x06,
29 0xFF, 0x81, 0x3F, 0xFC, 0x06, 0xFF, 0x81, 0x3F, 0xFC, 0x06, 0xFF, 0x81, 0x3F, 0xFC, 0x06, 0xFF,
30 0x81, 0x3F, 0xFC, 0x06, 0xFF, 0x81, 0x3F, 0xFC, 0x06, 0xFF, 0x80, 0x3F, 0x08, 0x00,
31};
32// clang-format on
diff --git a/keyboards/tzarc/djinn/graphics/lock-num-ON.qgf.h b/keyboards/tzarc/djinn/graphics/lock-num-ON.qgf.h
new file mode 100644
index 0000000000..d714e88828
--- /dev/null
+++ b/keyboards/tzarc/djinn/graphics/lock-num-ON.qgf.h
@@ -0,0 +1,11 @@
1// Copyright 2022 QMK -- generated source code only, image retains original copyright
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4// This file was auto-generated by `qmk painter-convert-graphics -i lock-num-ON.png -f mono4`
5
6#pragma once
7
8#include <qp.h>
9
10extern const uint32_t gfx_lock_num_ON_length;
11extern const uint8_t gfx_lock_num_ON[302];
diff --git a/keyboards/tzarc/djinn/graphics/lock-scrl-OFF.qgf.c b/keyboards/tzarc/djinn/graphics/lock-scrl-OFF.qgf.c
new file mode 100644
index 0000000000..c31e4619ef
--- /dev/null
+++ b/keyboards/tzarc/djinn/graphics/lock-scrl-OFF.qgf.c
@@ -0,0 +1,32 @@
1// Copyright 2022 QMK -- generated source code only, image retains original copyright
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4// This file was auto-generated by `qmk painter-convert-graphics -i lock-scrl-OFF.png -f mono4`
5
6#include <qp.h>
7
8const uint32_t gfx_lock_scrl_OFF_length = 292;
9
10// clang-format off
11const uint8_t gfx_lock_scrl_OFF[292] = {
12 0x00, 0xFF, 0x12, 0x00, 0x00, 0x51, 0x47, 0x46, 0x01, 0x24, 0x01, 0x00, 0x00, 0xDB, 0xFE, 0xFF,
13 0xFF, 0x20, 0x00, 0x20, 0x00, 0x01, 0x00, 0x01, 0xFE, 0x04, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
14 0x02, 0xFD, 0x06, 0x00, 0x00, 0x01, 0x00, 0x01, 0xFF, 0xE8, 0x03, 0x05, 0xFA, 0xF4, 0x00, 0x00,
15 0x08, 0x00, 0x80, 0xFC, 0x04, 0xFF, 0x80, 0x0F, 0x02, 0x00, 0x80, 0xFC, 0x04, 0xFF, 0x80, 0x3F,
16 0x02, 0x00, 0x80, 0x3C, 0x04, 0x00, 0x80, 0xFC, 0x02, 0x00, 0x80, 0x3C, 0x04, 0x00, 0x83, 0xF0,
17 0x03, 0x00, 0x3C, 0x04, 0x00, 0x83, 0xC0, 0x0F, 0x00, 0x3C, 0x05, 0x00, 0x82, 0x3F, 0x00, 0x3C,
18 0x05, 0x00, 0x82, 0xFC, 0x00, 0x3C, 0x02, 0x00, 0x85, 0xC0, 0x03, 0x00, 0xF0, 0x03, 0x3C, 0x02,
19 0x00, 0x85, 0xC0, 0x03, 0x00, 0xC0, 0x0F, 0x3C, 0x02, 0x00, 0x81, 0xC0, 0x03, 0x02, 0x00, 0x81,
20 0x3F, 0x3C, 0x02, 0x00, 0x81, 0xC0, 0x03, 0x02, 0x00, 0x02, 0x3C, 0x02, 0x00, 0x81, 0xC0, 0x03,
21 0x02, 0x00, 0x02, 0x3C, 0x02, 0x00, 0x81, 0xC0, 0x03, 0x02, 0x00, 0x02, 0x3C, 0x02, 0x00, 0x81,
22 0xC0, 0x03, 0x02, 0x00, 0x02, 0x3C, 0x02, 0x00, 0x81, 0xC0, 0x03, 0x02, 0x00, 0x02, 0x3C, 0x02,
23 0x00, 0x81, 0xC0, 0x03, 0x02, 0x00, 0x02, 0x3C, 0x02, 0x00, 0x81, 0xC0, 0x03, 0x02, 0x00, 0x02,
24 0x3C, 0x80, 0x00, 0x02, 0xC0, 0x02, 0x03, 0x80, 0x00, 0x02, 0x3C, 0x81, 0x00, 0xF0, 0x02, 0xC3,
25 0x81, 0x0F, 0x00, 0x02, 0x3C, 0x85, 0x00, 0xC0, 0xCF, 0xF3, 0x03, 0x00, 0x02, 0x3C, 0x02, 0x00,
26 0x02, 0xFF, 0x02, 0x00, 0x02, 0x3C, 0x02, 0x00, 0x81, 0xFC, 0x3F, 0x02, 0x00, 0x02, 0x3C, 0x02,
27 0x00, 0x81, 0xF0, 0x0F, 0x02, 0x00, 0x02, 0x3C, 0x81, 0x00, 0xF0, 0x02, 0xFF, 0x81, 0x0F, 0x00,
28 0x02, 0x3C, 0x81, 0x00, 0xF0, 0x02, 0xFF, 0x81, 0x0F, 0x00, 0x02, 0x3C, 0x06, 0x00, 0x02, 0x3C,
29 0x06, 0x00, 0x02, 0x3C, 0x06, 0x00, 0x81, 0x3C, 0xFC, 0x06, 0xFF, 0x81, 0x3F, 0xFC, 0x06, 0xFF,
30 0x80, 0x3F, 0x08, 0x00,
31};
32// clang-format on
diff --git a/keyboards/tzarc/djinn/graphics/lock-scrl-OFF.qgf.h b/keyboards/tzarc/djinn/graphics/lock-scrl-OFF.qgf.h
new file mode 100644
index 0000000000..95e5f633cb
--- /dev/null
+++ b/keyboards/tzarc/djinn/graphics/lock-scrl-OFF.qgf.h
@@ -0,0 +1,11 @@
1// Copyright 2022 QMK -- generated source code only, image retains original copyright
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4// This file was auto-generated by `qmk painter-convert-graphics -i lock-scrl-OFF.png -f mono4`
5
6#pragma once
7
8#include <qp.h>
9
10extern const uint32_t gfx_lock_scrl_OFF_length;
11extern const uint8_t gfx_lock_scrl_OFF[292];
diff --git a/keyboards/tzarc/djinn/graphics/lock-scrl-ON.qgf.c b/keyboards/tzarc/djinn/graphics/lock-scrl-ON.qgf.c
new file mode 100644
index 0000000000..f1cc86493a
--- /dev/null
+++ b/keyboards/tzarc/djinn/graphics/lock-scrl-ON.qgf.c
@@ -0,0 +1,32 @@
1// Copyright 2022 QMK -- generated source code only, image retains original copyright
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4// This file was auto-generated by `qmk painter-convert-graphics -i lock-scrl-ON.png -f mono4`
5
6#include <qp.h>
7
8const uint32_t gfx_lock_scrl_ON_length = 296;
9
10// clang-format off
11const uint8_t gfx_lock_scrl_ON[296] = {
12 0x00, 0xFF, 0x12, 0x00, 0x00, 0x51, 0x47, 0x46, 0x01, 0x28, 0x01, 0x00, 0x00, 0xD7, 0xFE, 0xFF,
13 0xFF, 0x20, 0x00, 0x20, 0x00, 0x01, 0x00, 0x01, 0xFE, 0x04, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
14 0x02, 0xFD, 0x06, 0x00, 0x00, 0x01, 0x00, 0x01, 0xFF, 0xE8, 0x03, 0x05, 0xFA, 0xF8, 0x00, 0x00,
15 0x08, 0x00, 0x80, 0xFC, 0x04, 0xFF, 0x80, 0x0F, 0x02, 0x00, 0x80, 0xFC, 0x04, 0xFF, 0x80, 0x3F,
16 0x02, 0x00, 0x80, 0xFC, 0x05, 0xFF, 0x02, 0x00, 0x80, 0xFC, 0x05, 0xFF, 0x82, 0x03, 0x00, 0xFC,
17 0x05, 0xFF, 0x82, 0x0F, 0x00, 0xFC, 0x05, 0xFF, 0x82, 0x3F, 0x00, 0xFC, 0x06, 0xFF, 0x81, 0x00,
18 0xFC, 0x02, 0xFF, 0x81, 0x3F, 0xFC, 0x02, 0xFF, 0x81, 0x03, 0xFC, 0x02, 0xFF, 0x81, 0x3F, 0xFC,
19 0x02, 0xFF, 0x81, 0x0F, 0xFC, 0x02, 0xFF, 0x81, 0x3F, 0xFC, 0x02, 0xFF, 0x81, 0x3F, 0xFC, 0x02,
20 0xFF, 0x81, 0x3F, 0xFC, 0x02, 0xFF, 0x81, 0x3F, 0xFC, 0x02, 0xFF, 0x81, 0x3F, 0xFC, 0x02, 0xFF,
21 0x81, 0x3F, 0xFC, 0x02, 0xFF, 0x81, 0x3F, 0xFC, 0x02, 0xFF, 0x81, 0x3F, 0xFC, 0x02, 0xFF, 0x81,
22 0x3F, 0xFC, 0x02, 0xFF, 0x81, 0x3F, 0xFC, 0x02, 0xFF, 0x81, 0x3F, 0xFC, 0x02, 0xFF, 0x81, 0x3F,
23 0xFC, 0x02, 0xFF, 0x81, 0x3F, 0xFC, 0x02, 0xFF, 0x81, 0x3F, 0xFC, 0x02, 0xFF, 0x81, 0x3F, 0xFC,
24 0x02, 0xFF, 0x82, 0x3F, 0xFC, 0xFF, 0x02, 0x3F, 0x02, 0xFC, 0x84, 0xFF, 0x3F, 0xFC, 0xFF, 0x0F,
25 0x02, 0x3C, 0x8B, 0xF0, 0xFF, 0x3F, 0xFC, 0xFF, 0x3F, 0x30, 0x0C, 0xFC, 0xFF, 0x3F, 0xFC, 0x02,
26 0xFF, 0x02, 0x00, 0x02, 0xFF, 0x81, 0x3F, 0xFC, 0x02, 0xFF, 0x81, 0x03, 0xC0, 0x02, 0xFF, 0x81,
27 0x3F, 0xFC, 0x02, 0xFF, 0x81, 0x0F, 0xF0, 0x02, 0xFF, 0x83, 0x3F, 0xFC, 0xFF, 0x0F, 0x02, 0x00,
28 0x85, 0xF0, 0xFF, 0x3F, 0xFC, 0xFF, 0x0F, 0x02, 0x00, 0x83, 0xF0, 0xFF, 0x3F, 0xFC, 0x06, 0xFF,
29 0x81, 0x3F, 0xFC, 0x06, 0xFF, 0x81, 0x3F, 0xFC, 0x06, 0xFF, 0x81, 0x3F, 0xFC, 0x06, 0xFF, 0x81,
30 0x3F, 0xFC, 0x06, 0xFF, 0x80, 0x3F, 0x08, 0x00,
31};
32// clang-format on
diff --git a/keyboards/tzarc/djinn/graphics/lock-scrl-ON.qgf.h b/keyboards/tzarc/djinn/graphics/lock-scrl-ON.qgf.h
new file mode 100644
index 0000000000..f8ee67c002
--- /dev/null
+++ b/keyboards/tzarc/djinn/graphics/lock-scrl-ON.qgf.h
@@ -0,0 +1,11 @@
1// Copyright 2022 QMK -- generated source code only, image retains original copyright
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4// This file was auto-generated by `qmk painter-convert-graphics -i lock-scrl-ON.png -f mono4`
5
6#pragma once
7
8#include <qp.h>
9
10extern const uint32_t gfx_lock_scrl_ON_length;
11extern const uint8_t gfx_lock_scrl_ON[296];
diff --git a/keyboards/tzarc/djinn/graphics/theme_djinn_default.c b/keyboards/tzarc/djinn/graphics/theme_djinn_default.c
new file mode 100644
index 0000000000..616a3c2430
--- /dev/null
+++ b/keyboards/tzarc/djinn/graphics/theme_djinn_default.c
@@ -0,0 +1,307 @@
1// Copyright 2018-2022 Nick Brassel (@tzarc)
2// SPDX-License-Identifier: GPL-2.0-or-later
3#include QMK_KEYBOARD_H
4#include <hal.h>
5#include <string.h>
6#include <ctype.h>
7#include <printf.h>
8#include "qp.h"
9#include "backlight.h"
10#include "transactions.h"
11#include "split_util.h"
12
13#include "djinn.h"
14#include "theme_djinn_default.h"
15
16#include "djinn.qgf.h"
17#include "lock-caps-ON.qgf.h"
18#include "lock-scrl-ON.qgf.h"
19#include "lock-num-ON.qgf.h"
20#include "lock-caps-OFF.qgf.h"
21#include "lock-scrl-OFF.qgf.h"
22#include "lock-num-OFF.qgf.h"
23#include "thintel15.qff.h"
24
25static painter_image_handle_t djinn_logo;
26static painter_image_handle_t lock_caps_on;
27static painter_image_handle_t lock_caps_off;
28static painter_image_handle_t lock_num_on;
29static painter_image_handle_t lock_num_off;
30static painter_image_handle_t lock_scrl_on;
31static painter_image_handle_t lock_scrl_off;
32static painter_font_handle_t thintel;
33
34//----------------------------------------------------------
35// RGB Matrix naming
36#if defined(RGB_MATRIX_ENABLE)
37# include <rgb_matrix.h>
38
39# if defined(RGB_MATRIX_EFFECT)
40# undef RGB_MATRIX_EFFECT
41# endif // defined(RGB_MATRIX_EFFECT)
42
43# define RGB_MATRIX_EFFECT(x) RGB_MATRIX_EFFECT_##x,
44enum {
45 RGB_MATRIX_EFFECT_NONE,
46# include "rgb_matrix_effects.inc"
47# undef RGB_MATRIX_EFFECT
48# ifdef RGB_MATRIX_CUSTOM_KB
49# include "rgb_matrix_kb.inc"
50# endif
51# ifdef RGB_MATRIX_CUSTOM_USER
52# include "rgb_matrix_user.inc"
53# endif
54};
55
56# define RGB_MATRIX_EFFECT(x) \
57 case RGB_MATRIX_EFFECT_##x: \
58 return #x;
59const char *rgb_matrix_name(uint8_t effect) {
60 switch (effect) {
61 case RGB_MATRIX_EFFECT_NONE:
62 return "NONE";
63# include "rgb_matrix_effects.inc"
64# undef RGB_MATRIX_EFFECT
65# ifdef RGB_MATRIX_CUSTOM_KB
66# include "rgb_matrix_kb.inc"
67# endif
68# ifdef RGB_MATRIX_CUSTOM_USER
69# include "rgb_matrix_user.inc"
70# endif
71 default:
72 return "UNKNOWN";
73 }
74}
75#endif // defined(RGB_MATRIX_ENABLE)
76
77//----------------------------------------------------------
78// UI Initialisation
79void keyboard_post_init_display(void) {
80 djinn_logo = qp_load_image_mem(gfx_djinn);
81 lock_caps_on = qp_load_image_mem(gfx_lock_caps_ON);
82 lock_caps_off = qp_load_image_mem(gfx_lock_caps_OFF);
83 lock_num_on = qp_load_image_mem(gfx_lock_num_ON);
84 lock_num_off = qp_load_image_mem(gfx_lock_num_OFF);
85 lock_scrl_on = qp_load_image_mem(gfx_lock_scrl_ON);
86 lock_scrl_off = qp_load_image_mem(gfx_lock_scrl_OFF);
87 thintel = qp_load_font_mem(font_thintel15);
88}
89
90//----------------------------------------------------------
91// UI Drawing
92void draw_ui_user(void) {
93 bool hue_redraw = false;
94 static uint16_t last_hue = 0xFFFF;
95#if defined(RGB_MATRIX_ENABLE)
96 uint16_t curr_hue = rgb_matrix_get_hue();
97#else // defined(RGB_MATRIX_ENABLE)
98 uint16_t curr_hue = 0;
99#endif // defined(RGB_MATRIX_ENABLE)
100 if (last_hue != curr_hue) {
101 last_hue = curr_hue;
102 hue_redraw = true;
103 }
104
105 bool layer_state_redraw = false;
106 static uint32_t last_layer_state = 0;
107 if (last_layer_state != layer_state) {
108 last_layer_state = layer_state;
109 layer_state_redraw = true;
110 }
111
112 bool power_state_redraw = false;
113 static usbpd_allowance_t last_current_state = (usbpd_allowance_t)(~0);
114 if (last_current_state != kb_state.current_setting) {
115 last_current_state = kb_state.current_setting;
116 power_state_redraw = true;
117 }
118
119 bool scan_redraw = false;
120 static uint32_t last_scan_update = 0;
121 if (timer_elapsed32(last_scan_update) > 125) {
122 last_scan_update = timer_read32();
123 scan_redraw = true;
124 }
125
126 bool wpm_redraw = false;
127 static uint32_t last_wpm_update = 0;
128 if (timer_elapsed32(last_wpm_update) > 125) {
129 last_wpm_update = timer_read32();
130 wpm_redraw = true;
131 }
132
133#if defined(RGB_MATRIX_ENABLE)
134 bool rgb_effect_redraw = false;
135 static uint16_t last_effect = 0xFFFF;
136 uint8_t curr_effect = rgb_matrix_config.mode;
137 if (last_effect != curr_effect) {
138 last_effect = curr_effect;
139 rgb_effect_redraw = true;
140 }
141#endif // defined(RGB_MATRIX_ENABLE)
142
143 // Show the Djinn logo and two vertical bars on both sides
144 if (hue_redraw) {
145 qp_drawimage_recolor(lcd, 120 - djinn_logo->width / 2, 32, djinn_logo, curr_hue, 255, 255, curr_hue, 255, 0);
146 qp_rect(lcd, 0, 0, 8, 319, curr_hue, 255, 255, true);
147 qp_rect(lcd, 231, 0, 239, 319, curr_hue, 255, 255, true);
148 }
149
150 int ypos = 4;
151
152 // Show layer info on the left side
153 if (is_keyboard_left()) {
154 char buf[64] = {0};
155 int xpos = 16;
156
157#if defined(RGB_MATRIX_ENABLE)
158 if (hue_redraw || rgb_effect_redraw) {
159 static int max_rgb_xpos = 0;
160 xpos = 16;
161 snprintf_(buf, sizeof(buf), "rgb: %s", rgb_matrix_name(curr_effect));
162
163 for (int i = 5; i < sizeof(buf); ++i) {
164 if (buf[i] == 0)
165 break;
166 else if (buf[i] == '_')
167 buf[i] = ' ';
168 else if (buf[i - 1] == ' ')
169 buf[i] = toupper(buf[i]);
170 else if (buf[i - 1] != ' ')
171 buf[i] = tolower(buf[i]);
172 }
173
174 xpos += qp_drawtext_recolor(lcd, xpos, ypos, thintel, buf, curr_hue, 255, 255, curr_hue, 255, 0);
175 if (max_rgb_xpos < xpos) {
176 max_rgb_xpos = xpos;
177 }
178 qp_rect(lcd, xpos, ypos, max_rgb_xpos, ypos + thintel->line_height, 0, 0, 0, true);
179 }
180
181 ypos += thintel->line_height + 4;
182#endif // defined(RGB_MATRIX_ENABLE)
183
184 if (hue_redraw || layer_state_redraw) {
185 extern const char *current_layer_name(void);
186 const char *layer_name = current_layer_name();
187
188 static int max_layer_xpos = 0;
189 xpos = 16;
190 snprintf_(buf, sizeof(buf), "layer: %s", layer_name);
191 xpos += qp_drawtext_recolor(lcd, xpos, ypos, thintel, buf, curr_hue, 255, 255, curr_hue, 255, 0);
192 if (max_layer_xpos < xpos) {
193 max_layer_xpos = xpos;
194 }
195 qp_rect(lcd, xpos, ypos, max_layer_xpos, ypos + thintel->line_height, 0, 0, 0, true);
196 }
197
198 ypos += thintel->line_height + 4;
199
200 if (hue_redraw || power_state_redraw) {
201 static int max_power_xpos = 0;
202 xpos = 16;
203 snprintf_(buf, sizeof(buf), "power: %s", usbpd_str(kb_state.current_setting));
204 xpos += qp_drawtext_recolor(lcd, xpos, ypos, thintel, buf, curr_hue, 255, 255, curr_hue, 255, 0);
205 if (max_power_xpos < xpos) {
206 max_power_xpos = xpos;
207 }
208 qp_rect(lcd, xpos, ypos, max_power_xpos, ypos + thintel->line_height, 0, 0, 0, true);
209 }
210
211 ypos += thintel->line_height + 4;
212
213 if (hue_redraw || scan_redraw) {
214 static int max_scans_xpos = 0;
215 xpos = 16;
216 snprintf_(buf, sizeof(buf), "scans: %d", (int)theme_state.scan_rate);
217 xpos += qp_drawtext_recolor(lcd, xpos, ypos, thintel, buf, curr_hue, 255, 255, curr_hue, 255, 0);
218 if (max_scans_xpos < xpos) {
219 max_scans_xpos = xpos;
220 }
221 qp_rect(lcd, xpos, ypos, max_scans_xpos, ypos + thintel->line_height, 0, 0, 0, true);
222 }
223
224 ypos += thintel->line_height + 4;
225
226 if (hue_redraw || wpm_redraw) {
227 static int max_wpm_xpos = 0;
228 xpos = 16;
229 snprintf_(buf, sizeof(buf), "wpm: %d", (int)get_current_wpm());
230 xpos += qp_drawtext_recolor(lcd, xpos, ypos, thintel, buf, curr_hue, 255, 255, curr_hue, 255, 0);
231 if (max_wpm_xpos < xpos) {
232 max_wpm_xpos = xpos;
233 }
234 qp_rect(lcd, xpos, ypos, max_wpm_xpos, ypos + thintel->line_height, 0, 0, 0, true);
235 }
236
237 ypos += thintel->line_height + 4;
238 }
239
240 // Show LED lock indicators on the right side
241 if (!is_keyboard_left()) {
242 static led_t last_led_state = {0};
243 if (hue_redraw || last_led_state.raw != host_keyboard_led_state().raw) {
244 last_led_state.raw = host_keyboard_led_state().raw;
245 qp_drawimage_recolor(lcd, 239 - 12 - (32 * 3), 0, last_led_state.caps_lock ? lock_caps_on : lock_caps_off, curr_hue, 255, last_led_state.caps_lock ? 255 : 32, curr_hue, 255, 0);
246 qp_drawimage_recolor(lcd, 239 - 12 - (32 * 2), 0, last_led_state.num_lock ? lock_num_on : lock_num_off, curr_hue, 255, last_led_state.num_lock ? 255 : 32, curr_hue, 255, 0);
247 qp_drawimage_recolor(lcd, 239 - 12 - (32 * 1), 0, last_led_state.scroll_lock ? lock_scrl_on : lock_scrl_off, curr_hue, 255, last_led_state.scroll_lock ? 255 : 32, curr_hue, 255, 0);
248 }
249 }
250}
251
252//----------------------------------------------------------
253// Sync
254
255theme_runtime_config theme_state;
256
257void rpc_theme_sync_callback(uint8_t m2s_size, const void *m2s_buffer, uint8_t s2m_size, void *s2m_buffer) {
258 if (m2s_size == sizeof(theme_state)) {
259 memcpy(&theme_state, m2s_buffer, m2s_size);
260 }
261}
262
263void theme_init(void) {
264 // Register keyboard state sync split transaction
265 transaction_register_rpc(THEME_DATA_SYNC, rpc_theme_sync_callback);
266
267 // Reset the initial shared data value between master and slave
268 memset(&theme_state, 0, sizeof(theme_state));
269}
270
271void theme_state_update(void) {
272 if (is_keyboard_master()) {
273 // Keep the scan rate in sync
274 theme_state.scan_rate = get_matrix_scan_rate();
275 }
276}
277
278void theme_state_sync(void) {
279 if (!is_transport_connected()) return;
280
281 if (is_keyboard_master()) {
282 // Keep track of the last state, so that we can tell if we need to propagate to slave
283 static theme_runtime_config last_theme_state;
284 static uint32_t last_sync;
285 bool needs_sync = false;
286
287 // Check if the state values are different
288 if (memcmp(&theme_state, &last_theme_state, sizeof(theme_runtime_config))) {
289 needs_sync = true;
290 memcpy(&last_theme_state, &theme_state, sizeof(theme_runtime_config));
291 }
292
293 // Send to slave every 125ms regardless of state change
294 if (timer_elapsed32(last_sync) > 125) {
295 needs_sync = true;
296 }
297
298 // Perform the sync if requested
299 if (needs_sync) {
300 if (transaction_rpc_send(THEME_DATA_SYNC, sizeof(theme_runtime_config), &theme_state)) {
301 last_sync = timer_read32();
302 } else {
303 dprint("Failed to perform rpc call\n");
304 }
305 }
306 }
307}
diff --git a/keyboards/tzarc/djinn/graphics/theme_djinn_default.h b/keyboards/tzarc/djinn/graphics/theme_djinn_default.h
new file mode 100644
index 0000000000..4f3927e469
--- /dev/null
+++ b/keyboards/tzarc/djinn/graphics/theme_djinn_default.h
@@ -0,0 +1,19 @@
1// Copyright 2018-2022 Nick Brassel (@tzarc)
2// SPDX-License-Identifier: GPL-2.0-or-later
3#pragma once
4
5//----------------------------------------------------------
6// Sync
7
8#pragma pack(push)
9#pragma pack(1)
10typedef struct theme_runtime_config {
11 uint32_t scan_rate;
12} theme_runtime_config;
13#pragma pack(pop)
14
15extern theme_runtime_config theme_state;
16
17void theme_init(void);
18void theme_state_update(void);
19void theme_state_sync(void);
diff --git a/keyboards/tzarc/djinn/graphics/thintel15.qff.c b/keyboards/tzarc/djinn/graphics/thintel15.qff.c
new file mode 100644
index 0000000000..237f2e9e5f
--- /dev/null
+++ b/keyboards/tzarc/djinn/graphics/thintel15.qff.c
@@ -0,0 +1,74 @@
1// Copyright 2022 QMK -- generated source code only, font retains original copyright
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4// This file was auto-generated by `qmk painter-convert-font-image -i thintel15.png -f mono2`
5
6#include <qp.h>
7
8const uint32_t font_thintel15_length = 966;
9
10// clang-format off
11const uint8_t font_thintel15[966] = {
12 0x00, 0xFF, 0x14, 0x00, 0x00, 0x51, 0x46, 0x46, 0x01, 0xC6, 0x03, 0x00, 0x00, 0x39, 0xFC, 0xFF,
13 0xFF, 0x0B, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x01, 0xFE, 0x1D, 0x01, 0x00, 0x02, 0x00,
14 0x00, 0xC2, 0x00, 0x00, 0x84, 0x01, 0x00, 0x06, 0x03, 0x00, 0x46, 0x05, 0x00, 0x88, 0x07, 0x00,
15 0x46, 0x0A, 0x00, 0x82, 0x0C, 0x00, 0x43, 0x0D, 0x00, 0x83, 0x0E, 0x00, 0xC4, 0x0F, 0x00, 0x46,
16 0x11, 0x00, 0x83, 0x13, 0x00, 0xC5, 0x14, 0x00, 0x82, 0x16, 0x00, 0x44, 0x17, 0x00, 0xC5, 0x18,
17 0x00, 0x84, 0x1A, 0x00, 0x05, 0x1C, 0x00, 0xC5, 0x1D, 0x00, 0x85, 0x1F, 0x00, 0x45, 0x21, 0x00,
18 0x05, 0x23, 0x00, 0xC5, 0x24, 0x00, 0x85, 0x26, 0x00, 0x45, 0x28, 0x00, 0x02, 0x2A, 0x00, 0xC3,
19 0x2A, 0x00, 0x05, 0x2C, 0x00, 0xC5, 0x2D, 0x00, 0x85, 0x2F, 0x00, 0x45, 0x31, 0x00, 0x08, 0x33,
20 0x00, 0xC5, 0x35, 0x00, 0x85, 0x37, 0x00, 0x45, 0x39, 0x00, 0x05, 0x3B, 0x00, 0xC4, 0x3C, 0x00,
21 0x44, 0x3E, 0x00, 0xC5, 0x3F, 0x00, 0x85, 0x41, 0x00, 0x44, 0x43, 0x00, 0xC5, 0x44, 0x00, 0x85,
22 0x46, 0x00, 0x44, 0x48, 0x00, 0xC6, 0x49, 0x00, 0x06, 0x4C, 0x00, 0x45, 0x4E, 0x00, 0x05, 0x50,
23 0x00, 0xC5, 0x51, 0x00, 0x85, 0x53, 0x00, 0x45, 0x55, 0x00, 0x06, 0x57, 0x00, 0x45, 0x59, 0x00,
24 0x06, 0x5B, 0x00, 0x46, 0x5D, 0x00, 0x86, 0x5F, 0x00, 0xC6, 0x61, 0x00, 0x06, 0x64, 0x00, 0x44,
25 0x66, 0x00, 0xC4, 0x67, 0x00, 0x44, 0x69, 0x00, 0xC6, 0x6A, 0x00, 0x05, 0x6D, 0x00, 0xC3, 0x6E,
26 0x00, 0x05, 0x70, 0x00, 0xC5, 0x71, 0x00, 0x84, 0x73, 0x00, 0x05, 0x75, 0x00, 0xC5, 0x76, 0x00,
27 0x84, 0x78, 0x00, 0x05, 0x7A, 0x00, 0xC5, 0x7B, 0x00, 0x82, 0x7D, 0x00, 0x43, 0x7E, 0x00, 0x85,
28 0x7F, 0x00, 0x42, 0x81, 0x00, 0x06, 0x82, 0x00, 0x45, 0x84, 0x00, 0x05, 0x86, 0x00, 0xC5, 0x87,
29 0x00, 0x85, 0x89, 0x00, 0x44, 0x8B, 0x00, 0xC5, 0x8C, 0x00, 0x83, 0x8E, 0x00, 0xC5, 0x8F, 0x00,
30 0x86, 0x91, 0x00, 0xC6, 0x93, 0x00, 0x06, 0x96, 0x00, 0x45, 0x98, 0x00, 0x04, 0x9A, 0x00, 0x85,
31 0x9B, 0x00, 0x42, 0x9D, 0x00, 0x05, 0x9E, 0x00, 0xC5, 0x9F, 0x00, 0x04, 0xFB, 0x86, 0x02, 0x00,
32 0x00, 0x00, 0x00, 0x54, 0x45, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xFD, 0xD2,
33 0xAF, 0x28, 0x00, 0x00, 0x00, 0x84, 0x53, 0x15, 0x0E, 0x55, 0x39, 0x04, 0x00, 0x00, 0x00, 0x00,
34 0x12, 0x15, 0x0A, 0x28, 0x54, 0x24, 0x00, 0x00, 0x00, 0x80, 0x50, 0x14, 0x52, 0x95, 0x58, 0x00,
35 0x00, 0x00, 0x14, 0x00, 0x00, 0x4A, 0x92, 0x24, 0x02, 0x00, 0x91, 0x24, 0x49, 0x01, 0x00, 0x20,
36 0x27, 0x05, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x1F, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
37 0x60, 0x0A, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x24, 0x22,
38 0x11, 0x00, 0x00, 0xC0, 0xA4, 0x94, 0x52, 0x32, 0x00, 0x00, 0x20, 0x23, 0x22, 0x72, 0x00, 0x00,
39 0xC0, 0x24, 0x44, 0x44, 0x78, 0x00, 0x00, 0xC0, 0x24, 0x44, 0x50, 0x32, 0x00, 0x00, 0x80, 0x29,
40 0x95, 0x1E, 0x42, 0x00, 0x00, 0xE0, 0x85, 0x83, 0x50, 0x32, 0x00, 0x00, 0xC0, 0xA4, 0x70, 0x52,
41 0x32, 0x00, 0x00, 0xE0, 0x21, 0x42, 0x84, 0x10, 0x00, 0x00, 0xC0, 0xA4, 0x64, 0x52, 0x32, 0x00,
42 0x00, 0xC0, 0xA4, 0xE4, 0x50, 0x32, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x30, 0x60, 0x0A, 0x00,
43 0x00, 0x11, 0x11, 0x04, 0x41, 0x00, 0x00, 0x00, 0x80, 0x07, 0x1E, 0x00, 0x00, 0x00, 0x20, 0x08,
44 0x82, 0x88, 0x08, 0x00, 0x00, 0xC0, 0x24, 0x64, 0x04, 0x10, 0x00, 0x00, 0x00, 0x1C, 0x22, 0x59,
45 0x55, 0x2D, 0x02, 0x1C, 0x00, 0x00, 0x00, 0xC0, 0xA4, 0xF4, 0x52, 0x4A, 0x00, 0x00, 0xE0, 0xA4,
46 0x74, 0x52, 0x3A, 0x00, 0x00, 0xC0, 0xA4, 0x10, 0x42, 0x32, 0x00, 0x00, 0xE0, 0xA4, 0x94, 0x52,
47 0x3A, 0x00, 0x00, 0x70, 0x11, 0x17, 0x71, 0x00, 0x00, 0x70, 0x11, 0x17, 0x11, 0x00, 0x00, 0xC0,
48 0xA4, 0xD0, 0x52, 0x32, 0x00, 0x00, 0x20, 0xA5, 0xF4, 0x52, 0x4A, 0x00, 0x00, 0x70, 0x22, 0x22,
49 0x72, 0x00, 0x00, 0xC0, 0x21, 0x84, 0x50, 0x32, 0x00, 0x00, 0x20, 0xA5, 0x32, 0x4A, 0x4A, 0x00,
50 0x00, 0x10, 0x11, 0x11, 0x71, 0x00, 0x00, 0x40, 0xB4, 0x55, 0x51, 0x14, 0x45, 0x00, 0x00, 0x00,
51 0x40, 0x34, 0x55, 0x59, 0x14, 0x45, 0x00, 0x00, 0x00, 0xC0, 0xA4, 0x94, 0x52, 0x32, 0x00, 0x00,
52 0xE0, 0xA4, 0x74, 0x42, 0x08, 0x00, 0x00, 0xC0, 0xA4, 0x94, 0x52, 0x51, 0x00, 0x00, 0xE0, 0xA4,
53 0x74, 0x52, 0x4A, 0x00, 0x00, 0xC0, 0xA4, 0x60, 0x50, 0x32, 0x00, 0x00, 0xC0, 0x47, 0x10, 0x04,
54 0x41, 0x10, 0x00, 0x00, 0x00, 0x20, 0xA5, 0x94, 0x52, 0x32, 0x00, 0x00, 0x40, 0x14, 0x45, 0x51,
55 0xA4, 0x10, 0x00, 0x00, 0x00, 0x40, 0x14, 0x45, 0x51, 0xB5, 0x45, 0x00, 0x00, 0x00, 0x40, 0x14,
56 0x29, 0x84, 0x12, 0x45, 0x00, 0x00, 0x00, 0x40, 0x14, 0x45, 0x0E, 0x41, 0x10, 0x00, 0x00, 0x00,
57 0xC0, 0x07, 0x21, 0x84, 0x10, 0x7C, 0x00, 0x00, 0x00, 0x17, 0x11, 0x11, 0x11, 0x07, 0x00, 0x10,
58 0x21, 0x22, 0x44, 0x00, 0x00, 0x47, 0x44, 0x44, 0x44, 0x07, 0x00, 0x84, 0x12, 0x01, 0x00, 0x00,
59 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00,
60 0x00, 0x00, 0x93, 0x5C, 0x72, 0x00, 0x00, 0x20, 0x84, 0x93, 0x52, 0x3A, 0x00, 0x00, 0x00, 0x60,
61 0x11, 0x61, 0x00, 0x00, 0x00, 0x21, 0x97, 0x52, 0x72, 0x00, 0x00, 0x00, 0x00, 0x93, 0x5E, 0x70,
62 0x00, 0x00, 0x60, 0x11, 0x13, 0x11, 0x00, 0x00, 0x00, 0x00, 0x97, 0x52, 0x72, 0x28, 0x19, 0x20,
63 0x84, 0x93, 0x52, 0x4A, 0x00, 0x00, 0x10, 0x55, 0x00, 0x80, 0x20, 0x49, 0x0A, 0x00, 0x20, 0x84,
64 0x94, 0x4E, 0x4A, 0x00, 0x00, 0x54, 0x55, 0x00, 0x00, 0x00, 0x2C, 0x55, 0x55, 0x55, 0x00, 0x00,
65 0x00, 0x00, 0x80, 0x93, 0x52, 0x4A, 0x00, 0x00, 0x00, 0x00, 0x93, 0x52, 0x32, 0x00, 0x00, 0x00,
66 0x80, 0x93, 0x52, 0x3A, 0x21, 0x00, 0x00, 0x00, 0x97, 0x52, 0x72, 0x08, 0x01, 0x00, 0x50, 0x13,
67 0x11, 0x00, 0x00, 0x00, 0x00, 0x17, 0x0C, 0x3A, 0x00, 0x00, 0x48, 0x96, 0x44, 0x00, 0x00, 0x00,
68 0x80, 0x94, 0x52, 0x72, 0x00, 0x00, 0x00, 0x00, 0x44, 0x51, 0xA4, 0x10, 0x00, 0x00, 0x00, 0x00,
69 0x00, 0x44, 0x51, 0x54, 0x6D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x0A, 0xA1, 0x44, 0x00, 0x00,
70 0x00, 0x00, 0x80, 0x94, 0x52, 0x72, 0x28, 0x19, 0x00, 0x70, 0x24, 0x71, 0x00, 0x00, 0x4C, 0x08,
71 0x11, 0x84, 0x10, 0x0C, 0x00, 0x55, 0x55, 0x01, 0x83, 0x10, 0x82, 0x08, 0x21, 0x03, 0x00, 0x00,
72 0x00, 0xB0, 0x1A, 0x00, 0x00, 0x00,
73};
74// clang-format on
diff --git a/keyboards/tzarc/djinn/graphics/thintel15.qff.h b/keyboards/tzarc/djinn/graphics/thintel15.qff.h
new file mode 100644
index 0000000000..8e64bb45f3
--- /dev/null
+++ b/keyboards/tzarc/djinn/graphics/thintel15.qff.h
@@ -0,0 +1,11 @@
1// Copyright 2022 QMK -- generated source code only, font retains original copyright
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4// This file was auto-generated by `qmk painter-convert-font-image -i thintel15.png -f mono2`
5
6#pragma once
7
8#include <qp.h>
9
10extern const uint32_t font_thintel15_length;
11extern const uint8_t font_thintel15[966];
diff --git a/keyboards/tzarc/djinn/halconf.h b/keyboards/tzarc/djinn/halconf.h
new file mode 100644
index 0000000000..ae3576cec0
--- /dev/null
+++ b/keyboards/tzarc/djinn/halconf.h
@@ -0,0 +1,14 @@
1// Copyright 2018-2022 Nick Brassel (@tzarc)
2// SPDX-License-Identifier: GPL-2.0-or-later
3#pragma once
4
5#define HAL_USE_GPT TRUE
6#define HAL_USE_PWM TRUE
7#define HAL_USE_SPI TRUE
8#define HAL_USE_SERIAL TRUE
9#define SERIAL_BUFFERS_SIZE 256
10
11// This enables interrupt-driven mode
12#define PAL_USE_WAIT TRUE
13
14#include_next <halconf.h>
diff --git a/keyboards/tzarc/djinn/info.json b/keyboards/tzarc/djinn/info.json
new file mode 100644
index 0000000000..959663a6d6
--- /dev/null
+++ b/keyboards/tzarc/djinn/info.json
@@ -0,0 +1,140 @@
1{
2 "keyboard_name": "Djinn",
3 "manufacturer": "Tzarc",
4 "maintainer": "tzarc",
5 "url": "https://github.com/tzarc/djinn",
6 "processor": "STM32G474",
7 "bootloader": "stm32-dfu",
8 "bootloader_instructions": "Press the physical RESET button on the top of the board, or hold the top-left key when plugging in the board.",
9 "build": {
10 "lto": true
11 },
12 "debounce": 5,
13 "features": {
14 "audio": true,
15 "backlight": true,
16 "bootmagic": true,
17 "console": true,
18 "encoder": true,
19 "mousekey": true,
20 "extrakey": true,
21 "nkro": true,
22 "quantum_painter": true,
23 "rgb_matrix": true,
24 "unicode": false,
25 "usbpd": true,
26 "wpm": true
27 },
28 "matrix_pins": {
29 "custom_lite": true,
30 "rows": ["B13", "B14", "B15", "C6", "C7", "C8"],
31 "cols": ["C0", "C1", "C2", "C3", "A0", "A1", "A2"]
32 },
33 "backlight": {
34 "pin": "A7"
35 },
36 "split": {
37 "enabled": true,
38 "main": "pin"
39 },
40 "layouts": {
41 "LAYOUT_all": {
42 "layout": [
43 { "matrix": [0, 0], "label": "Esc", "x": 0, "y": 0.88 },
44 { "matrix": [0, 1], "label": "1", "x": 1, "y": 0.63 },
45 { "matrix": [0, 2], "label": "2", "x": 2, "y": 0.38 },
46 { "matrix": [0, 3], "label": "3", "x": 3, "y": 0 },
47 { "matrix": [0, 4], "label": "4", "x": 4, "y": 0.13 },
48 { "matrix": [0, 5], "label": "5", "x": 5, "y": 0.5 },
49 { "matrix": [0, 6], "label": "~", "x": 6, "y": 1 },
50
51 { "matrix": [6, 6], "label": "Del", "x": 12, "y": 1 },
52 { "matrix": [6, 5], "label": "6", "x": 13, "y": 0.5 },
53 { "matrix": [6, 4], "label": "7", "x": 14, "y": 0.13 },
54 { "matrix": [6, 3], "label": "8", "x": 15, "y": 0 },
55 { "matrix": [6, 2], "label": "9", "x": 16, "y": 0.38 },
56 { "matrix": [6, 1], "label": "0", "x": 17, "y": 0.63 },
57 { "matrix": [6, 0], "label": "Bksp", "x": 18, "y": 0.88 },
58
59 { "matrix": [1, 0], "label": "Tab", "x": 0, "y": 1.88 },
60 { "matrix": [1, 1], "label": "Q", "x": 1, "y": 1.63 },
61 { "matrix": [1, 2], "label": "W", "x": 2, "y": 1.38 },
62 { "matrix": [1, 3], "label": "E", "x": 3, "y": 1 },
63 { "matrix": [1, 4], "label": "R", "x": 4, "y": 1.13 },
64 { "matrix": [1, 5], "label": "T", "x": 5, "y": 1.5 },
65 { "matrix": [1, 6], "label": "[", "x": 6, "y": 2 },
66
67 { "matrix": [7, 6], "label": "]", "x": 12, "y": 2 },
68 { "matrix": [7, 5], "label": "Y", "x": 13, "y": 1.5 },
69 { "matrix": [7, 4], "label": "U", "x": 14, "y": 1.13 },
70 { "matrix": [7, 3], "label": "I", "x": 15, "y": 1 },
71 { "matrix": [7, 2], "label": "O", "x": 16, "y": 1.38 },
72 { "matrix": [7, 1], "label": "P", "x": 17, "y": 1.63 },
73 { "matrix": [7, 0], "label": "\\", "x": 18, "y": 1.88 },
74
75 { "matrix": [2, 0], "label": "Ctrl", "x": 0, "y": 2.88 },
76 { "matrix": [2, 1], "label": "A", "x": 1, "y": 2.63 },
77 { "matrix": [2, 2], "label": "S", "x": 2, "y": 2.38 },
78 { "matrix": [2, 3], "label": "D", "x": 3, "y": 2 },
79 { "matrix": [2, 4], "label": "F", "x": 4, "y": 2.13 },
80 { "matrix": [2, 5], "label": "G", "x": 5, "y": 2.5 },
81 { "matrix": [2, 6], "label": "Home", "x": 6, "y": 3 },
82
83 { "matrix": [8, 6], "label": "PgUp", "x": 12, "y": 3 },
84 { "matrix": [8, 5], "label": "H", "x": 13, "y": 2.5 },
85 { "matrix": [8, 4], "label": "J", "x": 14, "y": 2.13 },
86 { "matrix": [8, 3], "label": "K", "x": 15, "y": 2 },
87 { "matrix": [8, 2], "label": "L", "x": 16, "y": 2.38 },
88 { "matrix": [8, 1], "label": ";", "x": 17, "y": 2.63 },
89 { "matrix": [8, 0], "label": "\"", "x": 18, "y": 2.88 },
90
91 { "matrix": [3, 0], "label": "Shift", "x": 0, "y": 3.88 },
92 { "matrix": [3, 1], "label": "Z", "x": 1, "y": 3.63 },
93 { "matrix": [3, 2], "label": "X", "x": 2, "y": 3.38 },
94 { "matrix": [3, 3], "label": "C", "x": 3, "y": 3 },
95 { "matrix": [3, 4], "label": "V", "x": 4, "y": 3.13 },
96 { "matrix": [3, 5], "label": "B", "x": 5, "y": 3.5 },
97 { "matrix": [3, 6], "label": "End", "x": 6, "y": 4 },
98
99 { "matrix": [9, 6], "label": "PgDn", "x": 12, "y": 4 },
100 { "matrix": [9, 5], "label": "N", "x": 13, "y": 3.5 },
101 { "matrix": [9, 4], "label": "M", "x": 14, "y": 3.13 },
102 { "matrix": [9, 3], "label": ",", "x": 15, "y": 3 },
103 { "matrix": [9, 2], "label": ".", "x": 16, "y": 3.38 },
104 { "matrix": [9, 1], "label": "/", "x": 17, "y": 3.63 },
105 { "matrix": [9, 0], "label": "Shift", "x": 18, "y": 3.88 },
106
107 { "matrix": [4, 3], "label": "GUI", "x": 2.5, "y": 4.9 },
108 { "matrix": [4, 4], "label": "Lower", "x": 3.5, "y": 4.9 },
109 { "matrix": [4, 5], "label": "Space", "x": 4.5, "y": 5.06 },
110 { "matrix": [4, 6], "label": " ", "x": 5.5, "y": 5.4 },
111
112 { "matrix": [10, 6], "label": " ", "x": 12.5, "y": 5.4 },
113 { "matrix": [10, 5], "label": "Space", "x": 13.5, "y": 5.06 },
114 { "matrix": [10, 4], "label": "Raise", "x": 14.5, "y": 4.88 },
115 { "matrix": [10, 3], "label": "Alt", "x": 15.5, "y": 4.9 },
116
117 { "matrix": [5, 6], "label": "RGB", "x": 7.25, "y": 4.9 },
118 { "matrix": [11, 6], "label": "RGB", "x": 10.75, "y": 4.9 },
119
120 { "matrix": [5, 1], "label": "Up", "x": 4.5, "y": 7 },
121 { "matrix": [11, 1], "label": "Up", "x": 13.5, "y": 7 },
122
123 { "matrix": [5, 2], "label": "Left", "x": 3.5, "y": 8 },
124 { "matrix": [5, 5], "label": "Press", "x": 4.5, "y": 8 },
125 { "matrix": [5, 4], "label": "Right", "x": 5.5, "y": 8 },
126
127 { "matrix": [11, 2], "label": "Left", "x": 12.5, "y": 8 },
128 { "matrix": [11, 5], "label": "Press", "x": 13.5, "y": 8 },
129 { "matrix": [11, 4], "label": "Right", "x": 14.5, "y": 8 },
130
131 { "matrix": [5, 3], "label": "Down", "x": 4.5, "y": 9 },
132 { "matrix": [11, 3], "label": "Down", "x": 13.5, "y": 9 }
133 ]
134 }
135 },
136 "usb": {
137 "vid": "0x1209",
138 "pid": "0x4919"
139 }
140}
diff --git a/keyboards/tzarc/djinn/keymaps/default/config.h b/keyboards/tzarc/djinn/keymaps/default/config.h
new file mode 100644
index 0000000000..87e3e11665
--- /dev/null
+++ b/keyboards/tzarc/djinn/keymaps/default/config.h
@@ -0,0 +1,60 @@
1// Copyright 2018-2022 Nick Brassel (@tzarc)
2// SPDX-License-Identifier: GPL-2.0-or-later
3#pragma once
4
5// Encoder settings
6#define ENCODER_RESOLUTION 2
7
8// LCD blanking period
9#define LCD_ACTIVITY_TIMEOUT 30000
10
11// RGB settings
12#define RGB_MATRIX_KEYPRESSES
13#define RGB_MATRIX_FRAMEBUFFER_EFFECTS
14
15// Allow for an extra sync command over the split
16#define SPLIT_TRANSACTION_IDS_USER THEME_DATA_SYNC
17
18// RGB Effects
19#define ENABLE_RGB_MATRIX_ALPHAS_MODS
20#define ENABLE_RGB_MATRIX_GRADIENT_UP_DOWN
21#define ENABLE_RGB_MATRIX_GRADIENT_LEFT_RIGHT
22#define ENABLE_RGB_MATRIX_BREATHING
23#define ENABLE_RGB_MATRIX_BAND_SAT
24#define ENABLE_RGB_MATRIX_BAND_VAL
25#define ENABLE_RGB_MATRIX_BAND_PINWHEEL_SAT
26#define ENABLE_RGB_MATRIX_BAND_PINWHEEL_VAL
27#define ENABLE_RGB_MATRIX_BAND_SPIRAL_SAT
28#define ENABLE_RGB_MATRIX_BAND_SPIRAL_VAL
29#define ENABLE_RGB_MATRIX_CYCLE_ALL
30#define ENABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT
31#define ENABLE_RGB_MATRIX_CYCLE_UP_DOWN
32#define ENABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON
33#define ENABLE_RGB_MATRIX_CYCLE_OUT_IN
34#define ENABLE_RGB_MATRIX_CYCLE_OUT_IN_DUAL
35#define ENABLE_RGB_MATRIX_CYCLE_PINWHEEL
36#define ENABLE_RGB_MATRIX_CYCLE_SPIRAL
37#define ENABLE_RGB_MATRIX_DUAL_BEACON
38#define ENABLE_RGB_MATRIX_RAINBOW_BEACON
39#define ENABLE_RGB_MATRIX_RAINBOW_PINWHEELS
40#define ENABLE_RGB_MATRIX_RAINDROPS
41#define ENABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS
42#define ENABLE_RGB_MATRIX_HUE_BREATHING
43#define ENABLE_RGB_MATRIX_HUE_PENDULUM
44#define ENABLE_RGB_MATRIX_HUE_WAVE
45#define ENABLE_RGB_MATRIX_PIXEL_FRACTAL
46#define ENABLE_RGB_MATRIX_PIXEL_RAIN
47#define ENABLE_RGB_MATRIX_TYPING_HEATMAP
48#define ENABLE_RGB_MATRIX_DIGITAL_RAIN
49#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_SIMPLE
50#define ENABLE_RGB_MATRIX_SOLID_REACTIVE
51#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_WIDE
52#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE
53#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_CROSS
54#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTICROSS
55#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_NEXUS
56#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS
57#define ENABLE_RGB_MATRIX_SPLASH
58#define ENABLE_RGB_MATRIX_MULTISPLASH
59#define ENABLE_RGB_MATRIX_SOLID_SPLASH
60#define ENABLE_RGB_MATRIX_SOLID_MULTISPLASH \ No newline at end of file
diff --git a/keyboards/tzarc/djinn/keymaps/default/keymap.c b/keyboards/tzarc/djinn/keymaps/default/keymap.c
new file mode 100644
index 0000000000..32a53e27b8
--- /dev/null
+++ b/keyboards/tzarc/djinn/keymaps/default/keymap.c
@@ -0,0 +1,107 @@
1// Copyright 2018-2022 Nick Brassel (@tzarc)
2// SPDX-License-Identifier: GPL-2.0-or-later
3#include QMK_KEYBOARD_H
4#include "theme_djinn_default.h"
5
6// Layer definitions
7enum { _QWERTY, _LOWER, _RAISE, _ADJUST };
8
9//----------------------------------------------------------
10// Key map
11
12// clang-format off
13const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
14 [_QWERTY] = LAYOUT_all(
15 KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_GRV, KC_DEL, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC,
16 KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_LBRC, KC_RBRC, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSLS,
17 KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_HOME, KC_PGUP, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT,
18 KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_END, KC_PGDN, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_ENT,
19 KC_LGUI, MO(_LOWER),KC_SPC, KC_NO, KC_NO, KC_SPC, MO(_RAISE),KC_LALT,
20 RGB_RMOD, RGB_MOD,
21 KC_UP, KC_UP,
22 KC_LEFT, _______, KC_RIGHT, KC_LEFT, _______, KC_RIGHT,
23 KC_DOWN, KC_DOWN
24 ),
25 [_LOWER] = LAYOUT_all(
26 KC_F12, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, _______, _______, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11,
27 _______, _______, KC_UP, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
28 _______, KC_LEFT, KC_DOWN, KC_RIGHT,_______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
29 _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
30 _______, _______, _______, _______, _______, _______, _______, _______,
31 BL_DEC, BL_INC,
32 _______, _______,
33 _______, _______, _______, _______, _______, _______,
34 _______, _______
35 ),
36 [_RAISE] = LAYOUT_all(
37 KC_F12, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, _______, _______, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11,
38 _______,_______, KC_UP, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
39 _______,KC_LEFT, KC_DOWN, KC_RIGHT,_______, KC_UNDS, KC_NO, KC_NO, KC_EQL, _______, _______, _______, _______, _______,
40 _______, _______, _______, _______, _______, KC_MINS, KC_NO, KC_NO, KC_PLUS, _______, _______, _______, _______, _______,
41 _______, _______, _______, _______, _______, _______, _______, _______,
42 _______, _______,
43 _______, _______,
44 _______, _______, _______, _______, _______, _______,
45 _______, _______
46 ),
47 [_ADJUST] = LAYOUT_all(
48 _______, KC_CLCK, KC_NLCK, KC_SLCK, _______, _______, _______, _______, _______, _______, _______, DEBUG, EEP_RST, QK_BOOT,
49 _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
50 _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
51 _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
52 _______, _______, _______, _______, _______, _______, _______, _______,
53 _______, _______,
54 _______, _______,
55 _______, _______, _______, _______, _______, _______,
56 _______, _______
57 )
58};
59// clang-format on
60
61//----------------------------------------------------------
62// Encoder map
63
64// clang-format off
65const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][2] = {
66 [_QWERTY] = { ENCODER_CCW_CW(KC_MS_WH_UP, KC_MS_WH_DOWN), ENCODER_CCW_CW(KC_VOLD, KC_VOLU) },
67 [_LOWER] = { ENCODER_CCW_CW(RGB_HUD, RGB_HUI), ENCODER_CCW_CW(RGB_SAD, RGB_SAI) },
68 [_RAISE] = { ENCODER_CCW_CW(RGB_VAD, RGB_VAI), ENCODER_CCW_CW(RGB_SPD, RGB_SPI) },
69 [_ADJUST] = { ENCODER_CCW_CW(RGB_RMOD, RGB_MOD), ENCODER_CCW_CW(KC_LEFT, KC_RIGHT) },
70};
71// clang-format on
72
73//----------------------------------------------------------
74// Layer naming
75
76const char *current_layer_name(void) {
77 switch (get_highest_layer(layer_state)) {
78 case _QWERTY:
79 return "qwerty";
80 case _LOWER:
81 return "lower";
82 case _RAISE:
83 return "raise";
84 case _ADJUST:
85 return "adjust";
86 }
87 return "unknown";
88}
89
90//----------------------------------------------------------
91// Overrides
92
93void keyboard_post_init_user(void) {
94 // Initialise the theme
95 theme_init();
96
97 void keyboard_post_init_display(void);
98 keyboard_post_init_display();
99}
100
101void housekeeping_task_user(void) {
102 // Update kb_state so we can send to slave
103 theme_state_update();
104
105 // Data sync from master to slave
106 theme_state_sync();
107}
diff --git a/keyboards/tzarc/djinn/keymaps/default/rules.mk b/keyboards/tzarc/djinn/keymaps/default/rules.mk
new file mode 100644
index 0000000000..dbeb87a16c
--- /dev/null
+++ b/keyboards/tzarc/djinn/keymaps/default/rules.mk
@@ -0,0 +1,15 @@
1DEBUG_MATRIX_SCAN_RATE_ENABLE ?= api
2ENCODER_MAP_ENABLE = yes
3SWAP_HANDS_ENABLE = no
4
5VPATH += keyboards/tzarc/djinn/graphics
6SRC += \
7 theme_djinn_default.c \
8 djinn.qgf.c \
9 lock-caps-ON.qgf.c \
10 lock-scrl-ON.qgf.c \
11 lock-num-ON.qgf.c \
12 lock-caps-OFF.qgf.c \
13 lock-scrl-OFF.qgf.c \
14 lock-num-OFF.qgf.c \
15 thintel15.qff.c
diff --git a/keyboards/tzarc/djinn/mcuconf.h b/keyboards/tzarc/djinn/mcuconf.h
new file mode 100644
index 0000000000..f3a7fbfb16
--- /dev/null
+++ b/keyboards/tzarc/djinn/mcuconf.h
@@ -0,0 +1,30 @@
1// Copyright 2018-2022 Nick Brassel (@tzarc)
2// SPDX-License-Identifier: GPL-2.0-or-later
3#pragma once
4#include_next <mcuconf.h>
5
6// Used for audio
7#undef STM32_PWM_USE_TIM1
8#undef STM32_GPT_USE_TIM6
9#undef STM32_GPT_USE_TIM7
10#undef STM32_GPT_USE_TIM8
11#define STM32_PWM_USE_TIM1 TRUE
12#define STM32_GPT_USE_TIM6 TRUE
13#define STM32_GPT_USE_TIM7 TRUE
14#define STM32_GPT_USE_TIM8 TRUE
15
16// Used for backlight
17#undef STM32_PWM_USE_TIM17
18#define STM32_PWM_USE_TIM17 TRUE
19
20// Used for SK6812 chain
21#undef STM32_PWM_USE_TIM20
22#define STM32_PWM_USE_TIM20 TRUE
23
24// Used for split comms
25#undef STM32_SERIAL_USE_USART3
26#define STM32_SERIAL_USE_USART3 TRUE
27
28// Used for EEPROM/LCD
29#undef STM32_SPI_USE_SPI3
30#define STM32_SPI_USE_SPI3 TRUE
diff --git a/keyboards/tzarc/djinn/readme.md b/keyboards/tzarc/djinn/readme.md
new file mode 100644
index 0000000000..5cb9e9339c
--- /dev/null
+++ b/keyboards/tzarc/djinn/readme.md
@@ -0,0 +1,27 @@
1# Djinn
2
3![Djinn](https://i.imgur.com/ArSjkv8.jpg)
4
5The Djinn is a 64-key split keyboard -- dual 4x7 with a 4-key thumb cluster and encoders. It also has a 5-way tactile switch under the thumb. Oh, and two displays.
6
7Keyboard Maintainer: [tzarc](https://github.com/tzarc)
8Hardware Supported: Djinn: rev1, rev2
9Hardware Availability: [Open-source](https://github.com/tzarc/djinn)
10
11Make example for this keyboard (after setting up your build environment):
12
13 make tzarc/djinn/rev2:default
14
15Flashing example for this keyboard:
16
17 make tzarc/djinn/rev2:default:flash
18
19See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
20
21## Bootloader
22
23Enter the bootloader in 3 ways:
24
25* **Bootmagic reset**: Hold down the top-left key and plug in the keyboard.
26* **Physical reset button**: Briefly press the button on the back of the PCB.
27* **Keycode in layout**: Press the key mapped to `QK_BOOT` if it is available.
diff --git a/keyboards/tzarc/djinn/rev1/config.h b/keyboards/tzarc/djinn/rev1/config.h
new file mode 100644
index 0000000000..14cdaf2fdb
--- /dev/null
+++ b/keyboards/tzarc/djinn/rev1/config.h
@@ -0,0 +1,35 @@
1// Copyright 2018-2022 Nick Brassel (@tzarc)
2// SPDX-License-Identifier: GPL-2.0-or-later
3#pragma once
4
5// Limit the backlight brightness
6#ifndef BACKLIGHT_LIMIT_VAL
7# define BACKLIGHT_LIMIT_VAL 144
8#endif // BACKLIGHT_LIMIT_VAL
9
10// Split configuration
11#define SPLIT_HAND_PIN B11
12#ifdef USE_PLUG_DETECT_PIN
13# define USB_VBUS_PIN B12
14#endif
15#define SERIAL_USART_DRIVER SD3
16#define SERIAL_USART_TX_PAL_MODE 7
17#define SOFT_SERIAL_PIN B9
18#ifndef SERIAL_USART_SPEED
19# define SERIAL_USART_SPEED 640000
20#endif // SERIAL_USART_SPEED
21
22// RGB configuration
23#define RGBLED_NUM 84
24#define DRIVER_LED_TOTAL 84
25#define RGB_MATRIX_SPLIT \
26 { 42, 42 }
27#define RGB_POWER_ENABLE_PIN B1
28#define RGB_CURR_1500mA_OK_PIN B0
29#define RGB_CURR_3000mA_OK_PIN C5
30
31// EEPROM configuration
32#define EXTERNAL_EEPROM_SPI_SLAVE_SELECT_PIN B5
33#define EXTERNAL_EEPROM_SPI_CLOCK_DIVISOR 8 // (160MHz/8) => 20MHz
34#define EXTERNAL_EEPROM_BYTE_COUNT 8192
35#define EXTERNAL_EEPROM_PAGE_SIZE 64 // it's FRAM, so it doesn't actually matter, this just sets the RAM buffer size
diff --git a/keyboards/tzarc/djinn/rev1/info.json b/keyboards/tzarc/djinn/rev1/info.json
new file mode 100644
index 0000000000..73ddbe9e41
--- /dev/null
+++ b/keyboards/tzarc/djinn/rev1/info.json
@@ -0,0 +1,98 @@
1{
2 "usb": {
3 "device_version": "1.0.0"
4 },
5 "split": {
6 "usb_detect": {
7 "enabled": true
8 }
9 },
10 "rgb_matrix": {
11 "layout": [
12 { "flags": 2, "x": 110, "y": 30 },
13 { "flags": 2, "x": 110, "y": 80 },
14 { "flags": 2, "x": 110, "y": 130 },
15 { "flags": 2, "x": 95, "y": 180 },
16 { "flags": 2, "x": 75, "y": 195 },
17 { "flags": 2, "x": 60, "y": 210 },
18 { "flags": 2, "x": 45, "y": 190 },
19 { "flags": 2, "x": 35, "y": 175 },
20 { "flags": 2, "x": 20, "y": 160 },
21 { "flags": 2, "x": 5, "y": 160 },
22 { "flags": 4, "matrix": [4, 3], "x": 78, "y": 150 },
23 { "flags": 4, "matrix": [4, 4], "x": 104, "y": 150 },
24 { "flags": 4, "matrix": [4, 5], "x": 130, "y": 150 },
25 { "flags": 4, "matrix": [4, 6], "x": 156, "y": 150 },
26 { "flags": 4, "matrix": [3, 6], "x": 156, "y": 120 },
27 { "flags": 4, "matrix": [3, 5], "x": 130, "y": 120 },
28 { "flags": 4, "matrix": [3, 4], "x": 104, "y": 120 },
29 { "flags": 4, "matrix": [3, 3], "x": 78, "y": 120 },
30 { "flags": 4, "matrix": [3, 2], "x": 52, "y": 120 },
31 { "flags": 4, "matrix": [3, 1], "x": 26, "y": 120 },
32 { "flags": 4, "matrix": [3, 0], "x": 0, "y": 120 },
33 { "flags": 4, "matrix": [2, 0], "x": 0, "y": 90 },
34 { "flags": 4, "matrix": [2, 1], "x": 26, "y": 90 },
35 { "flags": 4, "matrix": [2, 2], "x": 52, "y": 90 },
36 { "flags": 4, "matrix": [2, 3], "x": 78, "y": 90 },
37 { "flags": 4, "matrix": [2, 4], "x": 104, "y": 90 },
38 { "flags": 4, "matrix": [2, 5], "x": 130, "y": 90 },
39 { "flags": 4, "matrix": [2, 6], "x": 156, "y": 90 },
40 { "flags": 4, "matrix": [1, 6], "x": 156, "y": 60 },
41 { "flags": 4, "matrix": [1, 5], "x": 130, "y": 60 },
42 { "flags": 4, "matrix": [1, 4], "x": 104, "y": 60 },
43 { "flags": 4, "matrix": [1, 3], "x": 78, "y": 60 },
44 { "flags": 4, "matrix": [1, 2], "x": 52, "y": 60 },
45 { "flags": 4, "matrix": [1, 1], "x": 26, "y": 60 },
46 { "flags": 4, "matrix": [1, 0], "x": 0, "y": 60 },
47 { "flags": 4, "matrix": [0, 0], "x": 0, "y": 30 },
48 { "flags": 4, "matrix": [0, 1], "x": 26, "y": 30 },
49 { "flags": 4, "matrix": [0, 2], "x": 52, "y": 30 },
50 { "flags": 4, "matrix": [0, 3], "x": 78, "y": 30 },
51 { "flags": 4, "matrix": [0, 4], "x": 104, "y": 30 },
52 { "flags": 4, "matrix": [0, 5], "x": 130, "y": 30 },
53 { "flags": 4, "matrix": [0, 6], "x": 156, "y": 30 },
54 { "flags": 2, "x": 114, "y": 30 },
55 { "flags": 2, "x": 114, "y": 80 },
56 { "flags": 2, "x": 114, "y": 130 },
57 { "flags": 2, "x": 129, "y": 180 },
58 { "flags": 2, "x": 149, "y": 195 },
59 { "flags": 2, "x": 164, "y": 210 },
60 { "flags": 2, "x": 179, "y": 190 },
61 { "flags": 2, "x": 189, "y": 175 },
62 { "flags": 2, "x": 204, "y": 160 },
63 { "flags": 2, "x": 219, "y": 160 },
64 { "flags": 4, "matrix": [10, 3], "x": 146, "y": 150 },
65 { "flags": 4, "matrix": [10, 4], "x": 120, "y": 150 },
66 { "flags": 4, "matrix": [10, 5], "x": 94, "y": 150 },
67 { "flags": 4, "matrix": [10, 6], "x": 68, "y": 150 },
68 { "flags": 4, "matrix": [9, 6], "x": 68, "y": 120 },
69 { "flags": 4, "matrix": [9, 5], "x": 94, "y": 120 },
70 { "flags": 4, "matrix": [9, 4], "x": 120, "y": 120 },
71 { "flags": 4, "matrix": [9, 3], "x": 146, "y": 120 },
72 { "flags": 4, "matrix": [9, 2], "x": 172, "y": 120 },
73 { "flags": 4, "matrix": [9, 1], "x": 198, "y": 120 },
74 { "flags": 4, "matrix": [9, 0], "x": 224, "y": 120 },
75 { "flags": 4, "matrix": [8, 0], "x": 224, "y": 90 },
76 { "flags": 4, "matrix": [8, 1], "x": 198, "y": 90 },
77 { "flags": 4, "matrix": [8, 2], "x": 172, "y": 90 },
78 { "flags": 4, "matrix": [8, 3], "x": 146, "y": 90 },
79 { "flags": 4, "matrix": [8, 4], "x": 120, "y": 90 },
80 { "flags": 4, "matrix": [8, 5], "x": 94, "y": 90 },
81 { "flags": 4, "matrix": [8, 6], "x": 68, "y": 90 },
82 { "flags": 4, "matrix": [7, 6], "x": 68, "y": 60 },
83 { "flags": 4, "matrix": [7, 5], "x": 94, "y": 60 },
84 { "flags": 4, "matrix": [7, 4], "x": 120, "y": 60 },
85 { "flags": 4, "matrix": [7, 3], "x": 146, "y": 60 },
86 { "flags": 4, "matrix": [7, 2], "x": 172, "y": 60 },
87 { "flags": 4, "matrix": [7, 1], "x": 198, "y": 60 },
88 { "flags": 4, "matrix": [7, 0], "x": 224, "y": 60 },
89 { "flags": 4, "matrix": [6, 0], "x": 224, "y": 30 },
90 { "flags": 4, "matrix": [6, 1], "x": 198, "y": 30 },
91 { "flags": 4, "matrix": [6, 2], "x": 172, "y": 30 },
92 { "flags": 4, "matrix": [6, 3], "x": 146, "y": 30 },
93 { "flags": 4, "matrix": [6, 4], "x": 120, "y": 30 },
94 { "flags": 4, "matrix": [6, 5], "x": 94, "y": 30 },
95 { "flags": 4, "matrix": [6, 6], "x": 68, "y": 30 }
96 ]
97 }
98}
diff --git a/keyboards/tzarc/djinn/rev1/rev1.c b/keyboards/tzarc/djinn/rev1/rev1.c
new file mode 100644
index 0000000000..95f0e20020
--- /dev/null
+++ b/keyboards/tzarc/djinn/rev1/rev1.c
@@ -0,0 +1,3 @@
1// Copyright 2018-2022 Nick Brassel (@tzarc)
2// SPDX-License-Identifier: GPL-2.0-or-later
3#include "rev1.h"
diff --git a/keyboards/tzarc/djinn/rev1/rev1.h b/keyboards/tzarc/djinn/rev1/rev1.h
new file mode 100644
index 0000000000..1845cb8fdd
--- /dev/null
+++ b/keyboards/tzarc/djinn/rev1/rev1.h
@@ -0,0 +1,3 @@
1// Copyright 2018-2022 Nick Brassel (@tzarc)
2// SPDX-License-Identifier: GPL-2.0-or-later
3#pragma once
diff --git a/keyboards/tzarc/djinn/rev1/rules.mk b/keyboards/tzarc/djinn/rev1/rules.mk
new file mode 100644
index 0000000000..f468872849
--- /dev/null
+++ b/keyboards/tzarc/djinn/rev1/rules.mk
@@ -0,0 +1 @@
# Placeholder to make the build system work.
diff --git a/keyboards/tzarc/djinn/rev2/config.h b/keyboards/tzarc/djinn/rev2/config.h
new file mode 100644
index 0000000000..52c909d442
--- /dev/null
+++ b/keyboards/tzarc/djinn/rev2/config.h
@@ -0,0 +1,47 @@
1// Copyright 2018-2022 Nick Brassel (@tzarc)
2// SPDX-License-Identifier: GPL-2.0-or-later
3#pragma once
4
5// Limit the backlight brightness
6#ifndef BACKLIGHT_LIMIT_VAL
7# define BACKLIGHT_LIMIT_VAL 144
8#endif // BACKLIGHT_LIMIT_VAL
9
10// Split configuration
11#define SPLIT_HAND_PIN B9
12#define USB_VBUS_PIN B12
13#define SERIAL_USART_DRIVER SD3
14#define SERIAL_USART_PIN_SWAP
15#define SERIAL_USART_TX_PIN B10
16#define SERIAL_USART_TX_PAL_MODE 7
17#define SERIAL_USART_RX_PIN B11
18#define SERIAL_USART_RX_PAL_MODE 7
19#ifndef SERIAL_USART_SPEED
20# define SERIAL_USART_SPEED 1200000
21#endif // SERIAL_USART_SPEED
22#define SERIAL_USART_FULL_DUPLEX
23
24// RGB configuration
25#define RGBLED_NUM 86
26#define DRIVER_LED_TOTAL 86
27#define RGB_MATRIX_SPLIT \
28 { 43, 43 }
29#define RGB_POWER_ENABLE_PIN B0
30#define RGB_CURR_1500mA_OK_PIN C5
31#define RGB_CURR_3000mA_OK_PIN C4
32
33// EEPROM configuration
34#define EXTERNAL_EEPROM_SPI_SLAVE_SELECT_PIN B5
35#define EXTERNAL_EEPROM_SPI_CLOCK_DIVISOR 8 // (160MHz/8) => 20MHz
36#define EXTERNAL_EEPROM_BYTE_COUNT 8192
37#define EXTERNAL_EEPROM_PAGE_SIZE 64 // it's FRAM, so it doesn't actually matter, this just sets the RAM buffer size
38
39// External flash config
40#define EXTERNAL_FLASH_SPI_MODE 3
41#define EXTERNAL_FLASH_SPI_SLAVE_SELECT_PIN A8
42#define EXTERNAL_FLASH_SPI_CLOCK_DIVISOR 4 // (160MHz/4) => 40MHz
43#define EXTERNAL_FLASH_SIZE (4 * 1024 * 1024) // 32Mb/4MB capacity
44
45// Fault indicators
46#define BOARD_POWER_FAULT_PIN C9
47#define RGB_POWER_FAULT_PIN C4
diff --git a/keyboards/tzarc/djinn/rev2/info.json b/keyboards/tzarc/djinn/rev2/info.json
new file mode 100644
index 0000000000..e9b151cb93
--- /dev/null
+++ b/keyboards/tzarc/djinn/rev2/info.json
@@ -0,0 +1,100 @@
1{
2 "usb": {
3 "device_version": "2.0.0"
4 },
5 "split": {
6 "usb_detect": {
7 "enabled": false
8 }
9 },
10 "rgb_matrix": {
11 "layout": [
12 { "flags": 2, "x": 110, "y": 30 },
13 { "flags": 2, "x": 110, "y": 80 },
14 { "flags": 2, "x": 110, "y": 130 },
15 { "flags": 2, "x": 95, "y": 180 },
16 { "flags": 2, "x": 75, "y": 195 },
17 { "flags": 2, "x": 60, "y": 210 },
18 { "flags": 2, "x": 45, "y": 190 },
19 { "flags": 2, "x": 35, "y": 175 },
20 { "flags": 2, "x": 20, "y": 160 },
21 { "flags": 2, "x": 5, "y": 160 },
22 { "flags": 2, "x": 5, "y": 160 },
23 { "flags": 4, "matrix": [4, 3], "x": 78, "y": 150 },
24 { "flags": 4, "matrix": [4, 4], "x": 104, "y": 150 },
25 { "flags": 4, "matrix": [4, 5], "x": 130, "y": 150 },
26 { "flags": 4, "matrix": [4, 6], "x": 156, "y": 150 },
27 { "flags": 4, "matrix": [3, 6], "x": 156, "y": 120 },
28 { "flags": 4, "matrix": [3, 5], "x": 130, "y": 120 },
29 { "flags": 4, "matrix": [3, 4], "x": 104, "y": 120 },
30 { "flags": 4, "matrix": [3, 3], "x": 78, "y": 120 },
31 { "flags": 4, "matrix": [3, 2], "x": 52, "y": 120 },
32 { "flags": 4, "matrix": [3, 1], "x": 26, "y": 120 },
33 { "flags": 4, "matrix": [3, 0], "x": 0, "y": 120 },
34 { "flags": 4, "matrix": [2, 0], "x": 0, "y": 90 },
35 { "flags": 4, "matrix": [2, 1], "x": 26, "y": 90 },
36 { "flags": 4, "matrix": [2, 2], "x": 52, "y": 90 },
37 { "flags": 4, "matrix": [2, 3], "x": 78, "y": 90 },
38 { "flags": 4, "matrix": [2, 4], "x": 104, "y": 90 },
39 { "flags": 4, "matrix": [2, 5], "x": 130, "y": 90 },
40 { "flags": 4, "matrix": [2, 6], "x": 156, "y": 90 },
41 { "flags": 4, "matrix": [1, 6], "x": 156, "y": 60 },
42 { "flags": 4, "matrix": [1, 5], "x": 130, "y": 60 },
43 { "flags": 4, "matrix": [1, 4], "x": 104, "y": 60 },
44 { "flags": 4, "matrix": [1, 3], "x": 78, "y": 60 },
45 { "flags": 4, "matrix": [1, 2], "x": 52, "y": 60 },
46 { "flags": 4, "matrix": [1, 1], "x": 26, "y": 60 },
47 { "flags": 4, "matrix": [1, 0], "x": 0, "y": 60 },
48 { "flags": 4, "matrix": [0, 0], "x": 0, "y": 30 },
49 { "flags": 4, "matrix": [0, 1], "x": 26, "y": 30 },
50 { "flags": 4, "matrix": [0, 2], "x": 52, "y": 30 },
51 { "flags": 4, "matrix": [0, 3], "x": 78, "y": 30 },
52 { "flags": 4, "matrix": [0, 4], "x": 104, "y": 30 },
53 { "flags": 4, "matrix": [0, 5], "x": 130, "y": 30 },
54 { "flags": 4, "matrix": [0, 6], "x": 156, "y": 30 },
55 { "flags": 2, "x": 114, "y": 30 },
56 { "flags": 2, "x": 114, "y": 80 },
57 { "flags": 2, "x": 114, "y": 130 },
58 { "flags": 2, "x": 129, "y": 180 },
59 { "flags": 2, "x": 149, "y": 195 },
60 { "flags": 2, "x": 164, "y": 210 },
61 { "flags": 2, "x": 179, "y": 190 },
62 { "flags": 2, "x": 189, "y": 175 },
63 { "flags": 2, "x": 24, "y": 160 },
64 { "flags": 2, "x": 219, "y": 160 },
65 { "flags": 2, "x": 219, "y": 160 },
66 { "flags": 4, "matrix": [10, 3], "x": 146, "y": 150 },
67 { "flags": 4, "matrix": [10, 4], "x": 120, "y": 150 },
68 { "flags": 4, "matrix": [10, 5], "x": 94, "y": 150 },
69 { "flags": 4, "matrix": [10, 6], "x": 68, "y": 150 },
70 { "flags": 4, "matrix": [9, 6], "x": 68, "y": 120 },
71 { "flags": 4, "matrix": [9, 5], "x": 94, "y": 120 },
72 { "flags": 4, "matrix": [9, 4], "x": 120, "y": 120 },
73 { "flags": 4, "matrix": [9, 3], "x": 146, "y": 120 },
74 { "flags": 4, "matrix": [9, 2], "x": 172, "y": 120 },
75 { "flags": 4, "matrix": [9, 1], "x": 198, "y": 120 },
76 { "flags": 4, "matrix": [9, 0], "x": 224, "y": 120 },
77 { "flags": 4, "matrix": [8, 0], "x": 224, "y": 90 },
78 { "flags": 4, "matrix": [8, 1], "x": 198, "y": 90 },
79 { "flags": 4, "matrix": [8, 2], "x": 172, "y": 90 },
80 { "flags": 4, "matrix": [8, 3], "x": 146, "y": 90 },
81 { "flags": 4, "matrix": [8, 4], "x": 120, "y": 90 },
82 { "flags": 4, "matrix": [8, 5], "x": 94, "y": 90 },
83 { "flags": 4, "matrix": [8, 6], "x": 68, "y": 90 },
84 { "flags": 4, "matrix": [7, 6], "x": 68, "y": 60 },
85 { "flags": 4, "matrix": [7, 5], "x": 94, "y": 60 },
86 { "flags": 4, "matrix": [7, 4], "x": 120, "y": 60 },
87 { "flags": 4, "matrix": [7, 3], "x": 146, "y": 60 },
88 { "flags": 4, "matrix": [7, 2], "x": 172, "y": 60 },
89 { "flags": 4, "matrix": [7, 1], "x": 198, "y": 60 },
90 { "flags": 4, "matrix": [7, 0], "x": 224, "y": 60 },
91 { "flags": 4, "matrix": [6, 0], "x": 224, "y": 30 },
92 { "flags": 4, "matrix": [6, 1], "x": 198, "y": 30 },
93 { "flags": 4, "matrix": [6, 2], "x": 172, "y": 30 },
94 { "flags": 4, "matrix": [6, 3], "x": 146, "y": 30 },
95 { "flags": 4, "matrix": [6, 4], "x": 120, "y": 30 },
96 { "flags": 4, "matrix": [6, 5], "x": 94, "y": 30 },
97 { "flags": 4, "matrix": [6, 6], "x": 68, "y": 30 }
98 ]
99 }
100}
diff --git a/keyboards/tzarc/djinn/rev2/rev2.c b/keyboards/tzarc/djinn/rev2/rev2.c
new file mode 100644
index 0000000000..f55e0c224a
--- /dev/null
+++ b/keyboards/tzarc/djinn/rev2/rev2.c
@@ -0,0 +1,3 @@
1// Copyright 2018-2022 Nick Brassel (@tzarc)
2// SPDX-License-Identifier: GPL-2.0-or-later
3#include "rev2.h"
diff --git a/keyboards/tzarc/djinn/rev2/rev2.h b/keyboards/tzarc/djinn/rev2/rev2.h
new file mode 100644
index 0000000000..1845cb8fdd
--- /dev/null
+++ b/keyboards/tzarc/djinn/rev2/rev2.h
@@ -0,0 +1,3 @@
1// Copyright 2018-2022 Nick Brassel (@tzarc)
2// SPDX-License-Identifier: GPL-2.0-or-later
3#pragma once
diff --git a/keyboards/tzarc/djinn/rev2/rules.mk b/keyboards/tzarc/djinn/rev2/rules.mk
new file mode 100644
index 0000000000..f468872849
--- /dev/null
+++ b/keyboards/tzarc/djinn/rev2/rules.mk
@@ -0,0 +1 @@
# Placeholder to make the build system work.
diff --git a/keyboards/tzarc/djinn/rules.mk b/keyboards/tzarc/djinn/rules.mk
new file mode 100644
index 0000000000..2f343a5a9d
--- /dev/null
+++ b/keyboards/tzarc/djinn/rules.mk
@@ -0,0 +1,23 @@
1CUSTOM_MATRIX = lite
2
3SERIAL_DRIVER = usart
4
5BACKLIGHT_DRIVER = pwm
6
7WS2812_DRIVER = pwm
8CIE1931_CURVE = yes
9
10RGB_MATRIX_DRIVER = WS2812
11
12EEPROM_DRIVER = spi
13
14AUDIO_DRIVER = pwm_software
15
16QUANTUM_PAINTER_DRIVERS = ili9341_spi
17
18SRC += \
19 djinn_portscan_matrix.c \
20 djinn_split_sync.c \
21 djinn_usbpd.c
22
23DEFAULT_FOLDER = tzarc/djinn/rev2