aboutsummaryrefslogtreecommitdiff
path: root/keyboards/abacus
diff options
context:
space:
mode:
Diffstat (limited to 'keyboards/abacus')
-rw-r--r--keyboards/abacus/abacus.c17
-rw-r--r--keyboards/abacus/abacus.h41
-rw-r--r--keyboards/abacus/config.h108
-rw-r--r--keyboards/abacus/info.json59
-rw-r--r--keyboards/abacus/keymaps/default/keymap.json10
-rw-r--r--keyboards/abacus/keymaps/unicodemap/keymap.c150
-rw-r--r--keyboards/abacus/keymaps/unicodemap/readme.md4
-rw-r--r--keyboards/abacus/keymaps/unicodemap/rules.mk1
-rw-r--r--keyboards/abacus/readme.md15
-rw-r--r--keyboards/abacus/rules.mk21
10 files changed, 426 insertions, 0 deletions
diff --git a/keyboards/abacus/abacus.c b/keyboards/abacus/abacus.c
new file mode 100644
index 000000000..aef62aa92
--- /dev/null
+++ b/keyboards/abacus/abacus.c
@@ -0,0 +1,17 @@
1/* Copyright 2020 nickolaij
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include "abacus.h"
diff --git a/keyboards/abacus/abacus.h b/keyboards/abacus/abacus.h
new file mode 100644
index 000000000..7f221c3c3
--- /dev/null
+++ b/keyboards/abacus/abacus.h
@@ -0,0 +1,41 @@
1/* Copyright 2020 nickolaij
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#pragma once
18#include "quantum.h"
19#define XXX KC_NO
20
21
22/* This is a shortcut to help you visually see your layout.
23 *
24 * The first section contains all of the arguments representing the physical
25 * layout of the board and position of the keys.
26 *
27 * The second converts the arguments into a two-dimensional array which
28 * represents the switch matrix.
29 */
30#define LAYOUT( \
31 k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0a, k0b, \
32 k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1a, k1b, \
33 k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2a, k2b, \
34 k30, k31, k32, k33, k34, k35, k36, k37, k38 \
35) \
36{ \
37 { k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0a, k0b }, \
38 { k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1a, k1b }, \
39 { k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2a, k2b }, \
40 { k30, k31, k32, k33, XXX, XXX, k34, XXX, k35, k36, k37, k38} \
41}
diff --git a/keyboards/abacus/config.h b/keyboards/abacus/config.h
new file mode 100644
index 000000000..eee2f3f91
--- /dev/null
+++ b/keyboards/abacus/config.h
@@ -0,0 +1,108 @@
1/*
2Copyright 2020 nickolaij
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#pragma once
19
20#include "config_common.h"
21
22/* USB Device descriptor parameter */
23#define VENDOR_ID 0xFEED
24#define PRODUCT_ID 0x0000
25#define DEVICE_VER 0x0001
26#define MANUFACTURER nickolaij
27#define PRODUCT abacus
28
29/* key matrix size */
30#define MATRIX_ROWS 4
31#define MATRIX_COLS 12
32
33/*
34 * Keyboard Matrix Assignments
35 *
36 * Change this to how you wired your keyboard
37 * COLS: AVR pins used for columns, left to right
38 * ROWS: AVR pins used for rows, top to bottom
39 * DIODE_DIRECTION: COL2ROW = COL = Anode (+), ROW = Cathode (-, marked on diode)
40 * ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode)
41 *
42 */
43#define MATRIX_ROW_PINS { D3, D2, D4, C6 }
44#define MATRIX_COL_PINS { F4, F5, F6, F7, B1, D7, B3, E6, B2, B4, B6, B5}
45#define UNUSED_PINS {B0}
46
47#define DIP_SWITCH_PINS { D0 }
48
49#define ENCODERS_PAD_A { F1 }
50#define ENCODERS_PAD_B { F0 }
51#define ENCODER_RESOLUTION 4
52
53/* COL2ROW, ROW2COL*/
54#define DIODE_DIRECTION COL2ROW
55#define RGB_DI_PIN D1
56
57#ifdef RGB_DI_PIN
58# define RGBLED_NUM 17
59# define RGBLIGHT_HUE_STEP 8
60# define RGBLIGHT_SAT_STEP 8
61# define RGBLIGHT_VAL_STEP 8
62# define RGBLIGHT_LIMIT_VAL 255 /* The maximum brightness level */
63# define RGBLIGHT_SLEEP /* If defined, the RGB lighting will be switched off when the host goes to sleep */
64/*== choose animations ==*/
65# define RGBLIGHT_EFFECT_BREATHING
66# define RGBLIGHT_EFFECT_RAINBOW_MOOD
67# define RGBLIGHT_EFFECT_RAINBOW_SWIRL
68# define RGBLIGHT_EFFECT_SNAKE
69# define RGBLIGHT_EFFECT_KNIGHT
70# define RGBLIGHT_EFFECT_STATIC_GRADIENT
71/*== customize breathing effect ==*/
72/*==== (DEFAULT) use fixed table instead of exp() and sin() ====*/
73# define RGBLIGHT_BREATHE_TABLE_SIZE 256 // 256(default) or 128 or 64
74/*==== use exp() and sin() ====*/
75# define RGBLIGHT_EFFECT_BREATHE_CENTER 1.85 // 1 to 2.7
76# define RGBLIGHT_EFFECT_BREATHE_MAX 255 // 0 to 255
77#endif
78
79/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
80#define DEBOUNCE 5
81
82/* define if matrix has ghost (lacks anti-ghosting diodes) */
83//#define MATRIX_HAS_GHOST
84
85/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
86#define LOCKING_SUPPORT_ENABLE
87/* Locking resynchronize hack */
88#define LOCKING_RESYNC_ENABLE
89
90/*
91 * Feature disable options
92 * These options are also useful to firmware size reduction.
93 */
94
95/* disable debug print */
96//#define NO_DEBUG
97
98/* disable print */
99//#define NO_PRINT
100
101/* disable action features */
102//#define NO_ACTION_LAYER
103//#define NO_ACTION_TAPPING
104//#define NO_ACTION_ONESHOT
105
106/* disable these deprecated features by default */
107#define NO_ACTION_MACRO
108#define NO_ACTION_FUNCTION
diff --git a/keyboards/abacus/info.json b/keyboards/abacus/info.json
new file mode 100644
index 000000000..21d035c97
--- /dev/null
+++ b/keyboards/abacus/info.json
@@ -0,0 +1,59 @@
1{
2 "keyboard_name": "Abacus",
3 "url": "https://www.github.com/nickolaij",
4 "maintainer": "nickolaij",
5 "layouts": {
6 "LAYOUT": {
7 "layout": [
8 {"label":"k00", "x":0, "y":0, "w":1},
9 {"label":"k01", "x":1, "y":0, "w":1},
10 {"label":"k02", "x":2, "y":0, "w":1},
11 {"label":"k03", "x":3, "y":0, "w":1},
12 {"label":"k04", "x":4, "y":0, "w":1},
13 {"label":"k05", "x":5, "y":0, "w":1},
14 {"label":"k06", "x":6, "y":0, "w":1},
15 {"label":"k07", "x":7, "y":0, "w":1},
16 {"label":"k08", "x":8, "y":0, "w":1},
17 {"label":"k09", "x":9, "y":0, "w":1},
18 {"label":"k0a", "x":10, "y":0, "w":1},
19 {"label":"k0b", "x":11, "y":0, "w":1.75},
20
21 {"label":"k10", "x":0, "y":1, "w":1.25},
22 {"label":"k11", "x":1.25, "y":1, "w":1},
23 {"label":"k12", "x":2.25, "y":1, "w":1},
24 {"label":"k13", "x":3.25, "y":1, "w":1},
25 {"label":"k14", "x":4.25, "y":1, "w":1},
26 {"label":"k15", "x":5.25, "y":1, "w":1},
27 {"label":"k16", "x":6.25, "y":1, "w":1},
28 {"label":"k17", "x":7.25, "y":1, "w":1},
29 {"label":"k18", "x":8.25, "y":1, "w":1},
30 {"label":"k19", "x":9.25, "y":1, "w":1},
31 {"label":"k1a", "x":10.25, "y":1, "w":1},
32 {"label":"k1b", "x":11.25, "y":1, "w":1.5},
33
34 {"label":"k20", "x":0, "y":2, "w":1.75},
35 {"label":"k21", "x":1.75, "y":2, "w":1},
36 {"label":"k22", "x":2.75, "y":2, "w":1},
37 {"label":"k23", "x":3.75, "y":2, "w":1},
38 {"label":"k24", "x":4.75, "y":2, "w":1},
39 {"label":"k25", "x":5.75, "y":2, "w":1},
40 {"label":"k26", "x":6.75, "y":2, "w":1},
41 {"label":"k27", "x":7.75, "y":2, "w":1},
42 {"label":"k28", "x":8.75, "y":2, "w":1},
43 {"label":"k29", "x":9.75, "y":2, "w":1},
44 {"label":"k2a", "x":10.75, "y":2, "w":1},
45 {"label":"k2b", "x":11.75, "y":2, "w":1},
46
47 {"label":"k30", "x":0, "y":3, "w":1.25},
48 {"label":"k31", "x":1.25, "y":3, "w":1},
49 {"label":"k32", "x":2.25, "y":3, "w":1},
50 {"label":"k33", "x":3.25, "y":3, "w":2.75},
51 {"label":"k34", "x":6, "y":3, "w":2.75},
52 {"label":"k35", "x":8.75, "y":3, "w":1},
53 {"label":"k36", "x":9.75, "y":3, "w":1},
54 {"label":"k37", "x":10.75, "y":3, "w":1},
55 {"label":"k38", "x":11.75, "y":3, "w":1}
56 ]
57 }
58 }
59}
diff --git a/keyboards/abacus/keymaps/default/keymap.json b/keyboards/abacus/keymaps/default/keymap.json
new file mode 100644
index 000000000..506fd7ea6
--- /dev/null
+++ b/keyboards/abacus/keymaps/default/keymap.json
@@ -0,0 +1,10 @@
1{
2 "keyboard": "abacus",
3 "keymap": "default",
4 "layout": "LAYOUT",
5 "layers": [
6 ["KC_ESCAPE", "KC_Q", "KC_W", "KC_E", "KC_R", "KC_T", "KC_Y", "KC_U", "KC_I", "KC_O", "KC_P", "KC_BSPACE", "KC_TAB", "KC_A", "KC_S", "KC_D", "KC_F", "KC_G", "KC_H", "KC_J", "KC_K", "KC_L", "KC_SCOLON", "KC_BSLASH", "KC_LSHIFT", "KC_Z", "KC_X", "KC_C", "KC_V", "KC_B", "KC_N", "KC_M", "KC_COMMA", "KC_DOT", "KC_UP", "KC_DELETE", "KC_LCTRL", "KC_LGUI", "MO(1)", "KC_SPACE", "KC_ENTER", "MO(2)", "KC_LEFT", "KC_DOWN", "KC_RIGHT"],
7 ["KC_GRAVE", "KC_1", "KC_2", "KC_3", "KC_4", "KC_5", "KC_6", "KC_7", "KC_8", "KC_9", "KC_0", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_LBRACKET", "KC_RBRACKET", "KC_QUOTE", "KC_SLASH", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_MINUS", "KC_EQUAL", "KC_TRNS", "KC_TRNS", "KC_LALT", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_HOME", "KC_TRNS", "KC_END"],
8 ["KC_GRV", "KC_F1", "KC_F2", "KC_F3", "KC_F4", "KC_F5", "KC_F6", "KC_F7", "KC_F8", "KC_F9", "KC_F10", "KC_TRNS", "KC_TRNS", "KC_F11", "KC_F12", "RGB_MODE_PLAIN", "RGB_MODE_BREATHE", "RGB_MODE_RAINBOW", "RGB_MODE_SWIRL", "RGB_MODE_SNAKE", "RGB_MODE_KNIGHT", "RGB_MODE_GRADIENT", "KC_NO", "RGB_TOG", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "RGB_HUI", "KC_CAPS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS"]
9 ]
10}
diff --git a/keyboards/abacus/keymaps/unicodemap/keymap.c b/keyboards/abacus/keymaps/unicodemap/keymap.c
new file mode 100644
index 000000000..c31b268ca
--- /dev/null
+++ b/keyboards/abacus/keymaps/unicodemap/keymap.c
@@ -0,0 +1,150 @@
1/* Copyright 2020 nickolaij
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#include QMK_KEYBOARD_H
17
18// wait DELAY ms before unregistering media keys
19#define MEDIA_KEY_DELAY 10
20
21// Defines names for use in layer keycodes and the keymap
22enum layer_names {
23 _BASE,
24 _UPPER,
25 _LOWER
26};
27
28// Defines the keycodes used by our macros in process_record_user
29enum custom_keycodes {
30 NICKURL = SAFE_RANGE,
31 ALTTAB
32};
33
34enum unicode_names {
35 LOVEEYES,
36 THINK,
37 UPSIDEDOWN,
38 NOMOUTH,
39 PARTY,
40 HEART,
41 EGGPLANT,
42 PEACH,
43 EMOJI100,
44 EMOJIB
45};
46
47const uint32_t PROGMEM unicode_map[] = {
48 [LOVEEYES] = 0x1f60d,
49 [THINK] = 0x1f914,
50 [UPSIDEDOWN] = 0x1f643,
51 [NOMOUTH] = 0x1f636,
52 [PARTY] = 0x1f973,
53 [HEART] = 0x1f495,
54 [EMOJI100] = 0x1f4af,
55 [PEACH] = 0x1f351,
56 [EGGPLANT] = 0x1f346,
57 [EMOJIB] = 0x1f171
58};
59
60
61
62const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
63 /* Base */
64 [_BASE] = LAYOUT(
65 KC_ESCAPE, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPACE,
66 KC_TAB, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCOLON, KC_BSLASH,
67 KC_LSHIFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMMA, KC_DOT, KC_UP, KC_DELETE,
68 KC_LCTRL, KC_LGUI, MO(_UPPER), KC_SPACE, KC_ENTER, MO(_LOWER), KC_LEFT, KC_DOWN, KC_RIGHT
69 ),
70 [_UPPER] = LAYOUT(
71 KC_GRAVE, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, _______,
72 ALTTAB, _______, _______, _______, _______, _______, _______, _______, KC_LBRACKET, KC_RBRACKET, KC_QUOTE, KC_SLASH,
73 _______, _______, _______, _______, _______, _______, _______, _______, KC_MINUS, KC_EQUAL, _______, _______,
74 KC_LALT, _______, _______, _______, _______, _______, KC_HOME, _______, KC_END
75 ),
76 [_LOWER] = LAYOUT(
77 NICKURL, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, _______,
78 _______, KC_F11, KC_F12, RGB_MODE_PLAIN, RGB_MODE_BREATHE, RGB_MODE_RAINBOW, RGB_MODE_SWIRL, RGB_MODE_SNAKE, RGB_MODE_KNIGHT, RGB_MODE_GRADIENT, XXXXXXX, RGB_TOG,
79 _______, X(LOVEEYES), X(THINK), X(UPSIDEDOWN), X(NOMOUTH), X(PARTY), X(PEACH), X(HEART), X(EGGPLANT), X(EMOJI100), X(EMOJIB), RGB_HUI,
80 KC_CAPS, _______, _______, _______, _______, _______, _______, _______, _______
81 )
82
83
84};
85
86bool process_record_user(uint16_t keycode, keyrecord_t *record) {
87 switch (keycode) {
88 case NICKURL:
89 if (record->event.pressed) {
90 SEND_STRING("https://www.github.com/nickolaij");
91 } else {
92 tap_code(KC_ENTER);
93 }
94 return true;
95 break;
96
97 case ALTTAB:
98 if (record->event.pressed) {
99 tap_code16(A(KC_TAB));
100 }
101 return true;
102 break;
103
104 default:
105 return true;
106
107 }
108}
109
110
111bool dip_switch_update_user(uint8_t index, bool active) {
112 switch (index) {
113 case 0:
114 if(active) {
115 switch(get_highest_layer(layer_state)) {
116 case _BASE:
117 tap_code16(LCTL(KC_F));
118 break;
119 case _UPPER:
120 tap_code(KC_MUTE);
121 break;
122 case _LOWER:
123 tap_code(KC_MEDIA_PLAY_PAUSE);
124 break;
125 }
126 }
127 }
128 return true;
129}
130
131
132void matrix_init_user(void) {
133 set_unicode_input_mode(UC_WINC);
134}
135
136bool encoder_update_user(uint8_t index, bool clockwise) {
137
138 switch(get_highest_layer(layer_state)) {
139 case _BASE:
140 clockwise ? tap_code(KC_PGDN) : tap_code(KC_PGUP);
141 break;
142 case _UPPER:
143 clockwise ? tap_code(KC_VOLU) : tap_code(KC_VOLD);
144 break;
145 case _LOWER:
146 clockwise ? tap_code(KC_MEDIA_NEXT_TRACK) : tap_code(KC_MEDIA_PREV_TRACK);
147 break;
148 }
149 return true;
150}
diff --git a/keyboards/abacus/keymaps/unicodemap/readme.md b/keyboards/abacus/keymaps/unicodemap/readme.md
new file mode 100644
index 000000000..0c6098f0e
--- /dev/null
+++ b/keyboards/abacus/keymaps/unicodemap/readme.md
@@ -0,0 +1,4 @@
1# The default keymap for Abacus
2
3This is made based on my first few days of playing with it and honing in on what feels right.
4I've repurposed the DIP switch function for the encoder switches and added some functionality for multiple layers also effecting the encoders output.
diff --git a/keyboards/abacus/keymaps/unicodemap/rules.mk b/keyboards/abacus/keymaps/unicodemap/rules.mk
new file mode 100644
index 000000000..502b2def7
--- /dev/null
+++ b/keyboards/abacus/keymaps/unicodemap/rules.mk
@@ -0,0 +1 @@
UNICODEMAP_ENABLE = yes
diff --git a/keyboards/abacus/readme.md b/keyboards/abacus/readme.md
new file mode 100644
index 000000000..ecf25b2ed
--- /dev/null
+++ b/keyboards/abacus/readme.md
@@ -0,0 +1,15 @@
1# Abacus
2
3![abacus](https://i.imgur.com/IFtuWaK.jpg)
4
5A first attempt at a PCB design for a mechanical keyboard. Includes rotary encoder and RGB underglow.
6
7* Keyboard Maintainer: [nickolaij](https://github.com/nickolaij)
8* Hardware Supported: Abacus PCB, [Elite C Microcontroller](https://keeb.io/products/elite-c-usb-c-pro-micro-replacement-arduino-compatible-atmega32u4) or Pro Micro Microcontroller (Elite C has additional pins for encoder)
9* Hardware Availability: [Abacus PCB GitHub](https://github.com/nickolaij/Abacus_Rev2)
10
11Make example for this keyboard (after setting up your build environment):
12
13 make abacus:default
14
15See 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).
diff --git a/keyboards/abacus/rules.mk b/keyboards/abacus/rules.mk
new file mode 100644
index 000000000..96fe1ab97
--- /dev/null
+++ b/keyboards/abacus/rules.mk
@@ -0,0 +1,21 @@
1# MCU name
2MCU = atmega32u4
3
4# Bootloader selection
5BOOTLOADER = atmel-dfu
6
7# Build Options
8# change yes to no to disable
9#
10BOOTMAGIC_ENABLE = no # Enable Bootmagic Lite
11MOUSEKEY_ENABLE = no # Mouse keys
12EXTRAKEY_ENABLE = yes # Audio control and System control
13CONSOLE_ENABLE = yes # Console for debug
14COMMAND_ENABLE = yes # Commands for debug and configuration
15NKRO_ENABLE = no # Enable N-Key Rollover
16BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
17RGBLIGHT_ENABLE = yes # Enable keyboard RGB underglow
18AUDIO_ENABLE = no # Audio output
19ENCODER_ENABLE = yes
20DIP_SWITCH_ENABLE = yes
21LTO_ENABLE = yes