aboutsummaryrefslogtreecommitdiff
path: root/quantum
diff options
context:
space:
mode:
Diffstat (limited to 'quantum')
-rw-r--r--quantum/action.c5
-rw-r--r--quantum/audio/driver_chibios_pwm_hardware.c4
-rw-r--r--quantum/audio/song_list.h8
-rw-r--r--quantum/backlight/backlight_chibios.c10
-rw-r--r--quantum/eeconfig.c11
-rw-r--r--quantum/keyboard.c13
-rw-r--r--quantum/matrix.c28
-rw-r--r--quantum/mcu_selection.mk34
-rw-r--r--quantum/process_keycode/process_programmable_button.c31
-rw-r--r--quantum/process_keycode/process_programmable_button.h23
-rw-r--r--quantum/process_keycode/process_unicode_common.c47
-rw-r--r--quantum/programmable_button.c37
-rw-r--r--quantum/programmable_button.h30
-rw-r--r--quantum/quantum.c99
-rw-r--r--quantum/quantum.h4
-rw-r--r--quantum/quantum_keycodes.h70
-rw-r--r--quantum/usb_device_state.c51
-rw-r--r--quantum/usb_device_state.h39
18 files changed, 490 insertions, 54 deletions
diff --git a/quantum/action.c b/quantum/action.c
index be135f18f..95f39d23d 100644
--- a/quantum/action.c
+++ b/quantum/action.c
@@ -18,6 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
18#include "keycode.h" 18#include "keycode.h"
19#include "keyboard.h" 19#include "keyboard.h"
20#include "mousekey.h" 20#include "mousekey.h"
21#include "programmable_button.h"
21#include "command.h" 22#include "command.h"
22#include "led.h" 23#include "led.h"
23#include "action_layer.h" 24#include "action_layer.h"
@@ -988,6 +989,10 @@ void clear_keyboard_but_mods_and_keys() {
988 mousekey_clear(); 989 mousekey_clear();
989 mousekey_send(); 990 mousekey_send();
990#endif 991#endif
992#ifdef PROGRAMMABLE_BUTTON_ENABLE
993 programmable_button_clear();
994 programmable_button_send();
995#endif
991} 996}
992 997
993/** \brief Utilities for actions. (FIXME: Needs better description) 998/** \brief Utilities for actions. (FIXME: Needs better description)
diff --git a/quantum/audio/driver_chibios_pwm_hardware.c b/quantum/audio/driver_chibios_pwm_hardware.c
index 3c7d89b29..cd40019ee 100644
--- a/quantum/audio/driver_chibios_pwm_hardware.c
+++ b/quantum/audio/driver_chibios_pwm_hardware.c
@@ -109,9 +109,9 @@ void audio_driver_initialize(void) {
109 109
110 // connect the AUDIO_PIN to the PWM hardware 110 // connect the AUDIO_PIN to the PWM hardware
111#if defined(USE_GPIOV1) // STM32F103C8 111#if defined(USE_GPIOV1) // STM32F103C8
112 palSetLineMode(AUDIO_PIN, PAL_MODE_STM32_ALTERNATE_PUSHPULL); 112 palSetLineMode(AUDIO_PIN, PAL_MODE_ALTERNATE_PUSHPULL);
113#else // GPIOv2 (or GPIOv3 for f4xx, which is the same/compatible at this command) 113#else // GPIOv2 (or GPIOv3 for f4xx, which is the same/compatible at this command)
114 palSetLineMode(AUDIO_PIN, PAL_STM32_MODE_ALTERNATE | PAL_STM32_ALTERNATE(AUDIO_PWM_PAL_MODE)); 114 palSetLineMode(AUDIO_PIN, PAL_MODE_ALTERNATE(AUDIO_PWM_PAL_MODE));
115#endif 115#endif
116 116
117 gptStart(&AUDIO_STATE_TIMER, &gptCFG); 117 gptStart(&AUDIO_STATE_TIMER, &gptCFG);
diff --git a/quantum/audio/song_list.h b/quantum/audio/song_list.h
index b54b397e1..8e80a016a 100644
--- a/quantum/audio/song_list.h
+++ b/quantum/audio/song_list.h
@@ -20,11 +20,9 @@
20 20
21#include "musical_notes.h" 21#include "musical_notes.h"
22 22
23#if __GNUC__ > 5 // don't use for older gcc compilers since check isn't supported. 23#if __has_include("user_song_list.h")
24# if __has_include("user_song_list.h") 24# include "user_song_list.h"
25# include "user_song_list.h" 25#endif // if file exists
26# endif // if file exists
27#endif // __GNUC__
28 26
29#define NO_SOUND 27#define NO_SOUND
30 28
diff --git a/quantum/backlight/backlight_chibios.c b/quantum/backlight/backlight_chibios.c
index 4d5a69e14..7c6edd10d 100644
--- a/quantum/backlight/backlight_chibios.c
+++ b/quantum/backlight/backlight_chibios.c
@@ -8,9 +8,13 @@
8# define BACKLIGHT_LIMIT_VAL 255 8# define BACKLIGHT_LIMIT_VAL 255
9#endif 9#endif
10 10
11// GPIOV2 && GPIOV3
12#ifndef BACKLIGHT_PAL_MODE 11#ifndef BACKLIGHT_PAL_MODE
13# define BACKLIGHT_PAL_MODE 2 12# if defined(USE_GPIOV1)
13# define BACKLIGHT_PAL_MODE PAL_MODE_ALTERNATE_PUSHPULL
14# else
15// GPIOV2 && GPIOV3
16# define BACKLIGHT_PAL_MODE 5
17# endif
14#endif 18#endif
15 19
16// GENERIC 20// GENERIC
@@ -70,7 +74,7 @@ static uint32_t rescale_limit_val(uint32_t val) {
70 74
71void backlight_init_ports(void) { 75void backlight_init_ports(void) {
72#ifdef USE_GPIOV1 76#ifdef USE_GPIOV1
73 palSetPadMode(PAL_PORT(BACKLIGHT_PIN), PAL_PAD(BACKLIGHT_PIN), PAL_MODE_STM32_ALTERNATE_PUSHPULL); 77 palSetPadMode(PAL_PORT(BACKLIGHT_PIN), PAL_PAD(BACKLIGHT_PIN), BACKLIGHT_PAL_MODE);
74#else 78#else
75 palSetPadMode(PAL_PORT(BACKLIGHT_PIN), PAL_PAD(BACKLIGHT_PIN), PAL_MODE_ALTERNATE(BACKLIGHT_PAL_MODE)); 79 palSetPadMode(PAL_PORT(BACKLIGHT_PIN), PAL_PAD(BACKLIGHT_PIN), PAL_MODE_ALTERNATE(BACKLIGHT_PAL_MODE));
76#endif 80#endif
diff --git a/quantum/eeconfig.c b/quantum/eeconfig.c
index 92f0ac443..4c2ad2490 100644
--- a/quantum/eeconfig.c
+++ b/quantum/eeconfig.c
@@ -4,11 +4,6 @@
4#include "eeconfig.h" 4#include "eeconfig.h"
5#include "action_layer.h" 5#include "action_layer.h"
6 6
7#ifdef STM32_EEPROM_ENABLE
8# include <hal.h>
9# include "eeprom_stm32.h"
10#endif
11
12#if defined(EEPROM_DRIVER) 7#if defined(EEPROM_DRIVER)
13# include "eeprom_driver.h" 8# include "eeprom_driver.h"
14#endif 9#endif
@@ -43,9 +38,6 @@ __attribute__((weak)) void eeconfig_init_kb(void) {
43 * FIXME: needs doc 38 * FIXME: needs doc
44 */ 39 */
45void eeconfig_init_quantum(void) { 40void eeconfig_init_quantum(void) {
46#ifdef STM32_EEPROM_ENABLE
47 EEPROM_Erase();
48#endif
49#if defined(EEPROM_DRIVER) 41#if defined(EEPROM_DRIVER)
50 eeprom_driver_erase(); 42 eeprom_driver_erase();
51#endif 43#endif
@@ -111,9 +103,6 @@ void eeconfig_enable(void) { eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_N
111 * FIXME: needs doc 103 * FIXME: needs doc
112 */ 104 */
113void eeconfig_disable(void) { 105void eeconfig_disable(void) {
114#ifdef STM32_EEPROM_ENABLE
115 EEPROM_Erase();
116#endif
117#if defined(EEPROM_DRIVER) 106#if defined(EEPROM_DRIVER)
118 eeprom_driver_erase(); 107 eeprom_driver_erase();
119#endif 108#endif
diff --git a/quantum/keyboard.c b/quantum/keyboard.c
index b98fc64e4..6054faa03 100644
--- a/quantum/keyboard.c
+++ b/quantum/keyboard.c
@@ -76,6 +76,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
76#ifdef JOYSTICK_ENABLE 76#ifdef JOYSTICK_ENABLE
77# include "process_joystick.h" 77# include "process_joystick.h"
78#endif 78#endif
79#ifdef PROGRAMMABLE_BUTTON_ENABLE
80# include "programmable_button.h"
81#endif
79#ifdef HD44780_ENABLE 82#ifdef HD44780_ENABLE
80# include "hd44780.h" 83# include "hd44780.h"
81#endif 84#endif
@@ -97,9 +100,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
97#ifdef DIP_SWITCH_ENABLE 100#ifdef DIP_SWITCH_ENABLE
98# include "dip_switch.h" 101# include "dip_switch.h"
99#endif 102#endif
100#ifdef STM32_EEPROM_ENABLE
101# include "eeprom_stm32.h"
102#endif
103#ifdef EEPROM_DRIVER 103#ifdef EEPROM_DRIVER
104# include "eeprom_driver.h" 104# include "eeprom_driver.h"
105#endif 105#endif
@@ -246,9 +246,6 @@ void keyboard_setup(void) {
246 disable_jtag(); 246 disable_jtag();
247#endif 247#endif
248 print_set_sendchar(sendchar); 248 print_set_sendchar(sendchar);
249#ifdef STM32_EEPROM_ENABLE
250 EEPROM_Init();
251#endif
252#ifdef EEPROM_DRIVER 249#ifdef EEPROM_DRIVER
253 eeprom_driver_init(); 250 eeprom_driver_init();
254#endif 251#endif
@@ -548,6 +545,10 @@ MATRIX_LOOP_END:
548 digitizer_task(); 545 digitizer_task();
549#endif 546#endif
550 547
548#ifdef PROGRAMMABLE_BUTTON_ENABLE
549 programmable_button_send();
550#endif
551
551 // update LED 552 // update LED
552 if (led_status != host_keyboard_leds()) { 553 if (led_status != host_keyboard_leds()) {
553 led_status = host_keyboard_leds(); 554 led_status = host_keyboard_leds();
diff --git a/quantum/matrix.c b/quantum/matrix.c
index 33586c431..4fbcc2419 100644
--- a/quantum/matrix.c
+++ b/quantum/matrix.c
@@ -288,10 +288,8 @@ void matrix_init(void) {
288 matrix_init_pins(); 288 matrix_init_pins();
289 289
290 // initialize matrix state: all keys off 290 // initialize matrix state: all keys off
291 for (uint8_t i = 0; i < MATRIX_ROWS; i++) { 291 memset(matrix, 0, sizeof(matrix));
292 raw_matrix[i] = 0; 292 memset(raw_matrix, 0, sizeof(raw_matrix));
293 matrix[i] = 0;
294 }
295 293
296 debounce_init(ROWS_PER_HAND); 294 debounce_init(ROWS_PER_HAND);
297 295
@@ -312,24 +310,22 @@ __attribute__((weak)) bool transport_master_if_connected(matrix_row_t master_mat
312bool matrix_post_scan(void) { 310bool matrix_post_scan(void) {
313 bool changed = false; 311 bool changed = false;
314 if (is_keyboard_master()) { 312 if (is_keyboard_master()) {
313 static bool last_connected = false;
315 matrix_row_t slave_matrix[ROWS_PER_HAND] = {0}; 314 matrix_row_t slave_matrix[ROWS_PER_HAND] = {0};
316 if (transport_master_if_connected(matrix + thisHand, slave_matrix)) { 315 if (transport_master_if_connected(matrix + thisHand, slave_matrix)) {
317 for (int i = 0; i < ROWS_PER_HAND; ++i) { 316 changed = memcmp(matrix + thatHand, slave_matrix, sizeof(slave_matrix)) != 0;
318 if (matrix[thatHand + i] != slave_matrix[i]) {
319 matrix[thatHand + i] = slave_matrix[i];
320 changed = true;
321 }
322 }
323 } else {
324 // reset other half if disconnected
325 for (int i = 0; i < ROWS_PER_HAND; ++i) {
326 matrix[thatHand + i] = 0;
327 slave_matrix[i] = 0;
328 }
329 317
318 last_connected = true;
319 } else if (last_connected) {
320 // reset other half when disconnected
321 memset(slave_matrix, 0, sizeof(slave_matrix));
330 changed = true; 322 changed = true;
323
324 last_connected = false;
331 } 325 }
332 326
327 if (changed) memcpy(matrix + thatHand, slave_matrix, sizeof(slave_matrix));
328
333 matrix_scan_quantum(); 329 matrix_scan_quantum();
334 } else { 330 } else {
335 transport_slave(matrix + thatHand, matrix + thisHand); 331 transport_slave(matrix + thatHand, matrix + thisHand);
diff --git a/quantum/mcu_selection.mk b/quantum/mcu_selection.mk
index f7eaeec8a..92e3a7c92 100644
--- a/quantum/mcu_selection.mk
+++ b/quantum/mcu_selection.mk
@@ -81,7 +81,7 @@ ifneq ($(findstring MK20DX256, $(MCU)),)
81 BOARD ?= PJRC_TEENSY_3_1 81 BOARD ?= PJRC_TEENSY_3_1
82endif 82endif
83 83
84ifneq ($(findstring MK66F18, $(MCU)),) 84ifneq ($(findstring MK66FX1M0, $(MCU)),)
85 # Cortex version 85 # Cortex version
86 MCU = cortex-m4 86 MCU = cortex-m4
87 87
@@ -273,6 +273,38 @@ ifneq ($(findstring STM32F401, $(MCU)),)
273 UF2_FAMILY ?= STM32F4 273 UF2_FAMILY ?= STM32F4
274endif 274endif
275 275
276ifneq ($(findstring STM32F405, $(MCU)),)
277 # Cortex version
278 MCU = cortex-m4
279
280 # ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7
281 ARMV = 7
282
283 ## chip/board settings
284 # - the next two should match the directories in
285 # <chibios>/os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES)
286 MCU_FAMILY = STM32
287 MCU_SERIES = STM32F4xx
288
289 # Linker script to use
290 # - it should exist either in <chibios>/os/common/ports/ARMCMx/compilers/GCC/ld/
291 # or <keyboard_dir>/ld/
292 MCU_LDSCRIPT ?= STM32F405xG
293
294 # Startup code to use
295 # - it should exist in <chibios>/os/common/startup/ARMCMx/compilers/GCC/mk/
296 MCU_STARTUP ?= stm32f4xx
297
298 # Board: it should exist either in <chibios>/os/hal/boards/,
299 # <keyboard_dir>/boards/, or drivers/boards/
300 BOARD ?= GENERIC_STM32_F405XG
301
302 USE_FPU ?= yes
303
304 # UF2 settings
305 UF2_FAMILY ?= STM32F4
306endif
307
276ifneq ($(findstring STM32F407, $(MCU)),) 308ifneq ($(findstring STM32F407, $(MCU)),)
277 # Cortex version 309 # Cortex version
278 MCU = cortex-m4 310 MCU = cortex-m4
diff --git a/quantum/process_keycode/process_programmable_button.c b/quantum/process_keycode/process_programmable_button.c
new file mode 100644
index 000000000..c6e77faac
--- /dev/null
+++ b/quantum/process_keycode/process_programmable_button.c
@@ -0,0 +1,31 @@
1/*
2Copyright 2021 Thomas Weißschuh <thomas@t-8ch.de>
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#include "process_programmable_button.h"
19#include "programmable_button.h"
20
21bool process_programmable_button(uint16_t keycode, keyrecord_t *record) {
22 if (keycode >= PROGRAMMABLE_BUTTON_MIN && keycode <= PROGRAMMABLE_BUTTON_MAX) {
23 uint8_t button = keycode - PROGRAMMABLE_BUTTON_MIN + 1;
24 if (record->event.pressed) {
25 programmable_button_on(button);
26 } else {
27 programmable_button_off(button);
28 }
29 }
30 return true;
31}
diff --git a/quantum/process_keycode/process_programmable_button.h b/quantum/process_keycode/process_programmable_button.h
new file mode 100644
index 000000000..47c6ce561
--- /dev/null
+++ b/quantum/process_keycode/process_programmable_button.h
@@ -0,0 +1,23 @@
1/*
2Copyright 2021 Thomas Weißschuh <thomas@t-8ch.de>
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 <stdint.h>
21#include "quantum.h"
22
23bool process_programmable_button(uint16_t keycode, keyrecord_t *record);
diff --git a/quantum/process_keycode/process_unicode_common.c b/quantum/process_keycode/process_unicode_common.c
index 46fcaaa86..7853c22c5 100644
--- a/quantum/process_keycode/process_unicode_common.c
+++ b/quantum/process_keycode/process_unicode_common.c
@@ -22,6 +22,7 @@
22unicode_config_t unicode_config; 22unicode_config_t unicode_config;
23uint8_t unicode_saved_mods; 23uint8_t unicode_saved_mods;
24bool unicode_saved_caps_lock; 24bool unicode_saved_caps_lock;
25bool unicode_saved_num_lock;
25 26
26#if UNICODE_SELECTED_MODES != -1 27#if UNICODE_SELECTED_MODES != -1
27static uint8_t selected[] = {UNICODE_SELECTED_MODES}; 28static uint8_t selected[] = {UNICODE_SELECTED_MODES};
@@ -79,13 +80,14 @@ void persist_unicode_input_mode(void) { eeprom_update_byte(EECONFIG_UNICODEMODE,
79 80
80__attribute__((weak)) void unicode_input_start(void) { 81__attribute__((weak)) void unicode_input_start(void) {
81 unicode_saved_caps_lock = host_keyboard_led_state().caps_lock; 82 unicode_saved_caps_lock = host_keyboard_led_state().caps_lock;
83 unicode_saved_num_lock = host_keyboard_led_state().num_lock;
82 84
83 // Note the order matters here! 85 // Note the order matters here!
84 // Need to do this before we mess around with the mods, or else 86 // Need to do this before we mess around with the mods, or else
85 // UNICODE_KEY_LNX (which is usually Ctrl-Shift-U) might not work 87 // UNICODE_KEY_LNX (which is usually Ctrl-Shift-U) might not work
86 // correctly in the shifted case. 88 // correctly in the shifted case.
87 if (unicode_config.input_mode == UC_LNX && unicode_saved_caps_lock) { 89 if (unicode_config.input_mode == UC_LNX && unicode_saved_caps_lock) {
88 tap_code(KC_CAPS); 90 tap_code(KC_CAPSLOCK);
89 } 91 }
90 92
91 unicode_saved_mods = get_mods(); // Save current mods 93 unicode_saved_mods = get_mods(); // Save current mods
@@ -99,8 +101,12 @@ __attribute__((weak)) void unicode_input_start(void) {
99 tap_code16(UNICODE_KEY_LNX); 101 tap_code16(UNICODE_KEY_LNX);
100 break; 102 break;
101 case UC_WIN: 103 case UC_WIN:
104 // For increased reliability, use numpad keys for inputting digits
105 if (!unicode_saved_num_lock) {
106 tap_code(KC_NUMLOCK);
107 }
102 register_code(KC_LALT); 108 register_code(KC_LALT);
103 tap_code(KC_PPLS); 109 tap_code(KC_KP_PLUS);
104 break; 110 break;
105 case UC_WINC: 111 case UC_WINC:
106 tap_code(UNICODE_KEY_WINC); 112 tap_code(UNICODE_KEY_WINC);
@@ -117,13 +123,16 @@ __attribute__((weak)) void unicode_input_finish(void) {
117 unregister_code(UNICODE_KEY_MAC); 123 unregister_code(UNICODE_KEY_MAC);
118 break; 124 break;
119 case UC_LNX: 125 case UC_LNX:
120 tap_code(KC_SPC); 126 tap_code(KC_SPACE);
121 if (unicode_saved_caps_lock) { 127 if (unicode_saved_caps_lock) {
122 tap_code(KC_CAPS); 128 tap_code(KC_CAPSLOCK);
123 } 129 }
124 break; 130 break;
125 case UC_WIN: 131 case UC_WIN:
126 unregister_code(KC_LALT); 132 unregister_code(KC_LALT);
133 if (!unicode_saved_num_lock) {
134 tap_code(KC_NUMLOCK);
135 }
127 break; 136 break;
128 case UC_WINC: 137 case UC_WINC:
129 tap_code(KC_ENTER); 138 tap_code(KC_ENTER);
@@ -139,26 +148,44 @@ __attribute__((weak)) void unicode_input_cancel(void) {
139 unregister_code(UNICODE_KEY_MAC); 148 unregister_code(UNICODE_KEY_MAC);
140 break; 149 break;
141 case UC_LNX: 150 case UC_LNX:
142 tap_code(KC_ESC); 151 tap_code(KC_ESCAPE);
143 if (unicode_saved_caps_lock) { 152 if (unicode_saved_caps_lock) {
144 tap_code(KC_CAPS); 153 tap_code(KC_CAPSLOCK);
145 } 154 }
146 break; 155 break;
147 case UC_WINC: 156 case UC_WINC:
148 tap_code(KC_ESC); 157 tap_code(KC_ESCAPE);
149 break; 158 break;
150 case UC_WIN: 159 case UC_WIN:
151 unregister_code(KC_LALT); 160 unregister_code(KC_LALT);
161 if (!unicode_saved_num_lock) {
162 tap_code(KC_NUMLOCK);
163 }
152 break; 164 break;
153 } 165 }
154 166
155 set_mods(unicode_saved_mods); // Reregister previously set mods 167 set_mods(unicode_saved_mods); // Reregister previously set mods
156} 168}
157 169
170// clang-format off
171
172static void send_nibble_wrapper(uint8_t digit) {
173 if (unicode_config.input_mode == UC_WIN) {
174 uint8_t kc = digit < 10
175 ? KC_KP_1 + (10 + digit - 1) % 10
176 : KC_A + (digit - 10);
177 tap_code(kc);
178 return;
179 }
180 send_nibble(digit);
181}
182
183// clang-format on
184
158void register_hex(uint16_t hex) { 185void register_hex(uint16_t hex) {
159 for (int i = 3; i >= 0; i--) { 186 for (int i = 3; i >= 0; i--) {
160 uint8_t digit = ((hex >> (i * 4)) & 0xF); 187 uint8_t digit = ((hex >> (i * 4)) & 0xF);
161 send_nibble(digit); 188 send_nibble_wrapper(digit);
162 } 189 }
163} 190}
164 191
@@ -171,10 +198,10 @@ void register_hex32(uint32_t hex) {
171 uint8_t digit = ((hex >> (i * 4)) & 0xF); 198 uint8_t digit = ((hex >> (i * 4)) & 0xF);
172 if (digit == 0) { 199 if (digit == 0) {
173 if (!onzerostart) { 200 if (!onzerostart) {
174 send_nibble(digit); 201 send_nibble_wrapper(digit);
175 } 202 }
176 } else { 203 } else {
177 send_nibble(digit); 204 send_nibble_wrapper(digit);
178 onzerostart = false; 205 onzerostart = false;
179 } 206 }
180 } 207 }
diff --git a/quantum/programmable_button.c b/quantum/programmable_button.c
new file mode 100644
index 000000000..be828fd17
--- /dev/null
+++ b/quantum/programmable_button.c
@@ -0,0 +1,37 @@
1/*
2Copyright 2021 Thomas Weißschuh <thomas@t-8ch.de>
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#include "programmable_button.h"
19#include "host.h"
20
21#define REPORT_BIT(index) (((uint32_t)1) << (index - 1))
22
23static uint32_t programmable_button_report = 0;
24
25void programmable_button_clear(void) { programmable_button_report = 0; }
26
27void programmable_button_send(void) { host_programmable_button_send(programmable_button_report); }
28
29void programmable_button_on(uint8_t index) { programmable_button_report |= REPORT_BIT(index); }
30
31void programmable_button_off(uint8_t index) { programmable_button_report &= ~REPORT_BIT(index); }
32
33bool programmable_button_is_on(uint8_t index) { return !!(programmable_button_report & REPORT_BIT(index)); };
34
35uint32_t programmable_button_get_report(void) { return programmable_button_report; };
36
37void programmable_button_set_report(uint32_t report) { programmable_button_report = report; }
diff --git a/quantum/programmable_button.h b/quantum/programmable_button.h
new file mode 100644
index 000000000..e89b8b9fd
--- /dev/null
+++ b/quantum/programmable_button.h
@@ -0,0 +1,30 @@
1/*
2Copyright 2021 Thomas Weißschuh <thomas@t-8ch.de>
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 <stdint.h>
21#include <stdbool.h>
22#include "report.h"
23
24void programmable_button_clear(void);
25void programmable_button_send(void);
26void programmable_button_on(uint8_t index);
27void programmable_button_off(uint8_t index);
28bool programmable_button_is_on(uint8_t index);
29uint32_t programmable_button_get_report(void);
30void programmable_button_set_report(uint32_t report);
diff --git a/quantum/quantum.c b/quantum/quantum.c
index e60378afe..326c8370b 100644
--- a/quantum/quantum.c
+++ b/quantum/quantum.c
@@ -296,6 +296,9 @@ bool process_record_quantum(keyrecord_t *record) {
296#ifdef JOYSTICK_ENABLE 296#ifdef JOYSTICK_ENABLE
297 process_joystick(keycode, record) && 297 process_joystick(keycode, record) &&
298#endif 298#endif
299#ifdef PROGRAMMABLE_BUTTON_ENABLE
300 process_programmable_button(keycode, record) &&
301#endif
299 true)) { 302 true)) {
300 return false; 303 return false;
301 } 304 }
@@ -480,3 +483,99 @@ void api_send_unicode(uint32_t unicode) {
480__attribute__((weak)) void startup_user() {} 483__attribute__((weak)) void startup_user() {}
481 484
482__attribute__((weak)) void shutdown_user() {} 485__attribute__((weak)) void shutdown_user() {}
486
487/** \brief Run keyboard level Power down
488 *
489 * FIXME: needs doc
490 */
491__attribute__((weak)) void suspend_power_down_user(void) {}
492/** \brief Run keyboard level Power down
493 *
494 * FIXME: needs doc
495 */
496__attribute__((weak)) void suspend_power_down_kb(void) { suspend_power_down_user(); }
497
498void suspend_power_down_quantum(void) {
499#ifndef NO_SUSPEND_POWER_DOWN
500// Turn off backlight
501# ifdef BACKLIGHT_ENABLE
502 backlight_set(0);
503# endif
504
505# ifdef LED_MATRIX_ENABLE
506 led_matrix_task();
507# endif
508# ifdef RGB_MATRIX_ENABLE
509 rgb_matrix_task();
510# endif
511
512 // Turn off LED indicators
513 uint8_t leds_off = 0;
514# if defined(BACKLIGHT_CAPS_LOCK) && defined(BACKLIGHT_ENABLE)
515 if (is_backlight_enabled()) {
516 // Don't try to turn off Caps Lock indicator as it is backlight and backlight is already off
517 leds_off |= (1 << USB_LED_CAPS_LOCK);
518 }
519# endif
520 led_set(leds_off);
521
522// Turn off audio
523# ifdef AUDIO_ENABLE
524 stop_all_notes();
525# endif
526
527// Turn off underglow
528# if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE)
529 rgblight_suspend();
530# endif
531
532# if defined(LED_MATRIX_ENABLE)
533 led_matrix_set_suspend_state(true);
534# endif
535# if defined(RGB_MATRIX_ENABLE)
536 rgb_matrix_set_suspend_state(true);
537# endif
538
539# ifdef OLED_ENABLE
540 oled_off();
541# endif
542# ifdef ST7565_ENABLE
543 st7565_off();
544# endif
545#endif
546}
547
548/** \brief run user level code immediately after wakeup
549 *
550 * FIXME: needs doc
551 */
552__attribute__((weak)) void suspend_wakeup_init_user(void) {}
553
554/** \brief run keyboard level code immediately after wakeup
555 *
556 * FIXME: needs doc
557 */
558__attribute__((weak)) void suspend_wakeup_init_kb(void) { suspend_wakeup_init_user(); }
559
560__attribute__((weak)) void suspend_wakeup_init_quantum(void) {
561// Turn on backlight
562#ifdef BACKLIGHT_ENABLE
563 backlight_init();
564#endif
565
566 // Restore LED indicators
567 led_set(host_keyboard_leds());
568
569// Wake up underglow
570#if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE)
571 rgblight_wakeup();
572#endif
573
574#if defined(LED_MATRIX_ENABLE)
575 led_matrix_set_suspend_state(false);
576#endif
577#if defined(RGB_MATRIX_ENABLE)
578 rgb_matrix_set_suspend_state(false);
579#endif
580 suspend_wakeup_init_kb();
581}
diff --git a/quantum/quantum.h b/quantum/quantum.h
index 86b717e44..5cbe84d0c 100644
--- a/quantum/quantum.h
+++ b/quantum/quantum.h
@@ -147,6 +147,10 @@ extern layer_state_t layer_state;
147# include "process_joystick.h" 147# include "process_joystick.h"
148#endif 148#endif
149 149
150#ifdef PROGRAMMABLE_BUTTON_ENABLE
151# include "process_programmable_button.h"
152#endif
153
150#ifdef GRAVE_ESC_ENABLE 154#ifdef GRAVE_ESC_ENABLE
151# include "process_grave_esc.h" 155# include "process_grave_esc.h"
152#endif 156#endif
diff --git a/quantum/quantum_keycodes.h b/quantum/quantum_keycodes.h
index ef4b0f457..2ea81dd4c 100644
--- a/quantum/quantum_keycodes.h
+++ b/quantum/quantum_keycodes.h
@@ -524,6 +524,40 @@ enum quantum_keycodes {
524 // Additional magic key 524 // Additional magic key
525 MAGIC_TOGGLE_GUI, 525 MAGIC_TOGGLE_GUI,
526 526
527 // Programmable Button
528 PROGRAMMABLE_BUTTON_1,
529 PROGRAMMABLE_BUTTON_2,
530 PROGRAMMABLE_BUTTON_3,
531 PROGRAMMABLE_BUTTON_4,
532 PROGRAMMABLE_BUTTON_5,
533 PROGRAMMABLE_BUTTON_6,
534 PROGRAMMABLE_BUTTON_7,
535 PROGRAMMABLE_BUTTON_8,
536 PROGRAMMABLE_BUTTON_9,
537 PROGRAMMABLE_BUTTON_10,
538 PROGRAMMABLE_BUTTON_11,
539 PROGRAMMABLE_BUTTON_12,
540 PROGRAMMABLE_BUTTON_13,
541 PROGRAMMABLE_BUTTON_14,
542 PROGRAMMABLE_BUTTON_15,
543 PROGRAMMABLE_BUTTON_16,
544 PROGRAMMABLE_BUTTON_17,
545 PROGRAMMABLE_BUTTON_18,
546 PROGRAMMABLE_BUTTON_19,
547 PROGRAMMABLE_BUTTON_20,
548 PROGRAMMABLE_BUTTON_21,
549 PROGRAMMABLE_BUTTON_22,
550 PROGRAMMABLE_BUTTON_23,
551 PROGRAMMABLE_BUTTON_24,
552 PROGRAMMABLE_BUTTON_25,
553 PROGRAMMABLE_BUTTON_26,
554 PROGRAMMABLE_BUTTON_27,
555 PROGRAMMABLE_BUTTON_28,
556 PROGRAMMABLE_BUTTON_29,
557 PROGRAMMABLE_BUTTON_30,
558 PROGRAMMABLE_BUTTON_31,
559 PROGRAMMABLE_BUTTON_32,
560
527 // Start of custom keycode range for keyboards and keymaps - always leave at the end 561 // Start of custom keycode range for keyboards and keymaps - always leave at the end
528 SAFE_RANGE 562 SAFE_RANGE
529}; 563};
@@ -854,3 +888,39 @@ enum quantum_keycodes {
854#define OS_TOGG ONESHOT_TOGGLE 888#define OS_TOGG ONESHOT_TOGGLE
855#define OS_ON ONESHOT_ENABLE 889#define OS_ON ONESHOT_ENABLE
856#define OS_OFF ONESHOT_DISABLE 890#define OS_OFF ONESHOT_DISABLE
891
892// Programmable Button aliases
893#define PB_1 PROGRAMMABLE_BUTTON_1
894#define PB_2 PROGRAMMABLE_BUTTON_2
895#define PB_3 PROGRAMMABLE_BUTTON_3
896#define PB_4 PROGRAMMABLE_BUTTON_4
897#define PB_5 PROGRAMMABLE_BUTTON_5
898#define PB_6 PROGRAMMABLE_BUTTON_6
899#define PB_7 PROGRAMMABLE_BUTTON_7
900#define PB_8 PROGRAMMABLE_BUTTON_8
901#define PB_9 PROGRAMMABLE_BUTTON_9
902#define PB_10 PROGRAMMABLE_BUTTON_10
903#define PB_11 PROGRAMMABLE_BUTTON_11
904#define PB_12 PROGRAMMABLE_BUTTON_12
905#define PB_13 PROGRAMMABLE_BUTTON_13
906#define PB_14 PROGRAMMABLE_BUTTON_14
907#define PB_15 PROGRAMMABLE_BUTTON_15
908#define PB_16 PROGRAMMABLE_BUTTON_16
909#define PB_17 PROGRAMMABLE_BUTTON_17
910#define PB_18 PROGRAMMABLE_BUTTON_18
911#define PB_19 PROGRAMMABLE_BUTTON_19
912#define PB_20 PROGRAMMABLE_BUTTON_20
913#define PB_21 PROGRAMMABLE_BUTTON_21
914#define PB_22 PROGRAMMABLE_BUTTON_22
915#define PB_23 PROGRAMMABLE_BUTTON_23
916#define PB_24 PROGRAMMABLE_BUTTON_24
917#define PB_25 PROGRAMMABLE_BUTTON_25
918#define PB_26 PROGRAMMABLE_BUTTON_26
919#define PB_27 PROGRAMMABLE_BUTTON_27
920#define PB_28 PROGRAMMABLE_BUTTON_28
921#define PB_29 PROGRAMMABLE_BUTTON_29
922#define PB_30 PROGRAMMABLE_BUTTON_30
923#define PB_31 PROGRAMMABLE_BUTTON_31
924#define PB_32 PROGRAMMABLE_BUTTON_32
925#define PROGRAMMABLE_BUTTON_MIN PROGRAMMABLE_BUTTON_1
926#define PROGRAMMABLE_BUTTON_MAX PROGRAMMABLE_BUTTON_32
diff --git a/quantum/usb_device_state.c b/quantum/usb_device_state.c
new file mode 100644
index 000000000..5ccd309ec
--- /dev/null
+++ b/quantum/usb_device_state.c
@@ -0,0 +1,51 @@
1/*
2 * Copyright 2021 Andrei Purdea <andrei@purdea.ro>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "usb_device_state.h"
19
20enum usb_device_state usb_device_state = USB_DEVICE_STATE_NO_INIT;
21
22__attribute__((weak)) void notify_usb_device_state_change_kb(enum usb_device_state usb_device_state) { notify_usb_device_state_change_user(usb_device_state); }
23
24__attribute__((weak)) void notify_usb_device_state_change_user(enum usb_device_state usb_device_state) {}
25
26static void notify_usb_device_state_change(enum usb_device_state usb_device_state) { notify_usb_device_state_change_kb(usb_device_state); }
27
28void usb_device_state_set_configuration(bool isConfigured, uint8_t configurationNumber) {
29 usb_device_state = isConfigured ? USB_DEVICE_STATE_CONFIGURED : USB_DEVICE_STATE_INIT;
30 notify_usb_device_state_change(usb_device_state);
31}
32
33void usb_device_state_set_suspend(bool isConfigured, uint8_t configurationNumber) {
34 usb_device_state = USB_DEVICE_STATE_SUSPEND;
35 notify_usb_device_state_change(usb_device_state);
36}
37
38void usb_device_state_set_resume(bool isConfigured, uint8_t configurationNumber) {
39 usb_device_state = isConfigured ? USB_DEVICE_STATE_CONFIGURED : USB_DEVICE_STATE_INIT;
40 notify_usb_device_state_change(usb_device_state);
41}
42
43void usb_device_state_set_reset(void) {
44 usb_device_state = USB_DEVICE_STATE_INIT;
45 notify_usb_device_state_change(usb_device_state);
46}
47
48void usb_device_state_init(void) {
49 usb_device_state = USB_DEVICE_STATE_INIT;
50 notify_usb_device_state_change(usb_device_state);
51}
diff --git a/quantum/usb_device_state.h b/quantum/usb_device_state.h
new file mode 100644
index 000000000..c229311d4
--- /dev/null
+++ b/quantum/usb_device_state.h
@@ -0,0 +1,39 @@
1/*
2 * Copyright 2021 Andrei Purdea <andrei@purdea.ro>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#pragma once
19
20#include <stdbool.h>
21#include <stdint.h>
22
23void usb_device_state_set_configuration(bool isConfigured, uint8_t configurationNumber);
24void usb_device_state_set_suspend(bool isConfigured, uint8_t configurationNumber);
25void usb_device_state_set_resume(bool isConfigured, uint8_t configurationNumber);
26void usb_device_state_set_reset(void);
27void usb_device_state_init(void);
28
29enum usb_device_state {
30 USB_DEVICE_STATE_NO_INIT = 0, // We're in this state before calling usb_device_state_init()
31 USB_DEVICE_STATE_INIT = 1, // Can consume up to 100mA
32 USB_DEVICE_STATE_CONFIGURED = 2, // Can consume up to what is specified in configuration descriptor, typically 500mA
33 USB_DEVICE_STATE_SUSPEND = 3 // Can consume only suspend current
34};
35
36extern enum usb_device_state usb_device_state;
37
38void notify_usb_device_state_change_kb(enum usb_device_state usb_device_state);
39void notify_usb_device_state_change_user(enum usb_device_state usb_device_state);