aboutsummaryrefslogtreecommitdiff
path: root/quantum
diff options
context:
space:
mode:
Diffstat (limited to 'quantum')
-rw-r--r--quantum/dynamic_macro.h9
-rw-r--r--quantum/keymap.h13
-rw-r--r--quantum/keymap_extras/keymap_br_abnt2.h58
-rw-r--r--quantum/keymap_extras/keymap_dvp.h82
-rwxr-xr-xquantum/light_ws2812.c20
-rw-r--r--quantum/process_keycode/process_unicode.c51
-rw-r--r--quantum/process_keycode/process_unicode.h13
-rw-r--r--quantum/quantum.c2
-rw-r--r--quantum/rgblight.c61
-rw-r--r--quantum/rgblight.h6
-rw-r--r--quantum/variable_trace.c110
-rw-r--r--quantum/variable_trace.h34
12 files changed, 422 insertions, 37 deletions
diff --git a/quantum/dynamic_macro.h b/quantum/dynamic_macro.h
index a3ad61bc7..e6dbc5b9c 100644
--- a/quantum/dynamic_macro.h
+++ b/quantum/dynamic_macro.h
@@ -8,8 +8,13 @@
8/* May be overridden with a custom value. Be aware that the effective 8/* May be overridden with a custom value. Be aware that the effective
9 * macro length is half of this value: each keypress is recorded twice 9 * macro length is half of this value: each keypress is recorded twice
10 * because of the down-event and up-event. This is not a bug, it's the 10 * because of the down-event and up-event. This is not a bug, it's the
11 * intended behavior. */ 11 * intended behavior.
12#define DYNAMIC_MACRO_SIZE 256 12 *
13 * Usually it should be fine to set the macro size to at least 256 but
14 * there have been reports of it being too much in some users' cases,
15 * so 128 is considered a safe default.
16 */
17#define DYNAMIC_MACRO_SIZE 128
13#endif 18#endif
14 19
15/* DYNAMIC_MACRO_RANGE must be set as the last element of user's 20/* DYNAMIC_MACRO_RANGE must be set as the last element of user's
diff --git a/quantum/keymap.h b/quantum/keymap.h
index 41aa11622..ae56d16c7 100644
--- a/quantum/keymap.h
+++ b/quantum/keymap.h
@@ -84,6 +84,10 @@ enum quantum_keycodes {
84 QK_MOD_TAP_MAX = 0x6FFF, 84 QK_MOD_TAP_MAX = 0x6FFF,
85 QK_TAP_DANCE = 0x7100, 85 QK_TAP_DANCE = 0x7100,
86 QK_TAP_DANCE_MAX = 0x71FF, 86 QK_TAP_DANCE_MAX = 0x71FF,
87#ifdef UNICODEMAP_ENABLE
88 QK_UNICODE_MAP = 0x7800,
89 QK_UNICODE_MAP_MAX = 0x7FFF,
90#endif
87#ifdef UNICODE_ENABLE 91#ifdef UNICODE_ENABLE
88 QK_UNICODE = 0x8000, 92 QK_UNICODE = 0x8000,
89 QK_UNICODE_MAX = 0xFFFF, 93 QK_UNICODE_MAX = 0xFFFF,
@@ -195,6 +199,7 @@ enum quantum_keycodes {
195#define HYPR(kc) (kc | QK_LCTL | QK_LSFT | QK_LALT | QK_LGUI) 199#define HYPR(kc) (kc | QK_LCTL | QK_LSFT | QK_LALT | QK_LGUI)
196#define MEH(kc) (kc | QK_LCTL | QK_LSFT | QK_LALT) 200#define MEH(kc) (kc | QK_LCTL | QK_LSFT | QK_LALT)
197#define LCAG(kc) (kc | QK_LCTL | QK_LALT | QK_LGUI) 201#define LCAG(kc) (kc | QK_LCTL | QK_LALT | QK_LGUI)
202#define ALTG(kc) (kc | QK_RCTL | QK_RALT)
198 203
199#define MOD_HYPR 0xf 204#define MOD_HYPR 0xf
200#define MOD_MEH 0x7 205#define MOD_MEH 0x7
@@ -299,7 +304,10 @@ enum quantum_keycodes {
299// ON_PRESS = 1 304// ON_PRESS = 1
300// ON_RELEASE = 2 305// ON_RELEASE = 2
301// Unless you have a good reason not to do so, prefer ON_PRESS (1) as your default. 306// Unless you have a good reason not to do so, prefer ON_PRESS (1) as your default.
302#define TO(layer, when) (layer | QK_TO | (when << 0x4)) 307// In fact, we changed it to assume ON_PRESS for sanity/simplicity. If needed, you can add your own
308// keycode modeled after the old version, kept below for this.
309/* #define TO(layer, when) (layer | QK_TO | (when << 0x4)) */
310#define TO(layer) (layer | QK_TO | (ON_PRESS << 0x4))
303 311
304// Momentary switch layer - 256 layer max 312// Momentary switch layer - 256 layer max
305#define MO(layer) (layer | QK_MOMENTARY) 313#define MO(layer) (layer | QK_MOMENTARY)
@@ -339,5 +347,8 @@ enum quantum_keycodes {
339 #define UC(n) UNICODE(n) 347 #define UC(n) UNICODE(n)
340#endif 348#endif
341 349
350#ifdef UNICODEMAP_ENABLE
351 #define X(n) (n | QK_UNICODE_MAP)
352#endif
342 353
343#endif 354#endif
diff --git a/quantum/keymap_extras/keymap_br_abnt2.h b/quantum/keymap_extras/keymap_br_abnt2.h
new file mode 100644
index 000000000..0df177721
--- /dev/null
+++ b/quantum/keymap_extras/keymap_br_abnt2.h
@@ -0,0 +1,58 @@
1#ifndef KEYMAP_BR_ABNT2_H
2#define KEYMAP_BR_ABNT2_H
3
4#include "keymap_common.h"
5
6/* Scan codes for the Brazilian ABNT2 keyboard layout */
7
8#define BR_CCDL KC_SCLN // Ç same scancode as ;: on US layout
9#define BR_SCLN KC_SLSH // ;: same scancode as /? on US layout
10#define BR_QUOT KC_GRV // '" same scancode as `~ on US layout
11#define BR_TILD KC_QUOT // ~^ dead keys, same scancode as '" on US layout
12#define BR_ACUT KC_LBRC // ´` dead keys, same scancode as [{ on US layout
13#define BR_LBRC KC_RBRC // [{ same scancode as ]} on US layout
14#define BR_RBRC KC_BSLS // ]} same scancode as \| on US layout
15#define BR_BSLS KC_NUBS // \| uses the non-US hash scancode (#~, sometimes §±)
16#define BR_SLSH KC_INT1 // /? uses the INTL1 scancode
17
18#define BR_COLN LSFT(BR_SCLN) // shifted :
19#define BR_DQT LSFT(BR_QUOT) // shifted "
20#define BR_CIRC LSFT(BR_TILD) // shifted ^ (dead key)
21#define BR_GRAV LSFT(BR_ACUT) // shifted ` (dead key)
22#define BR_LCBR LSFT(BR_LBRC) // shifted {
23#define BR_RCBR LSFT(BR_RBRC) // shifted }
24#define BR_PIPE LSFT(BR_BSLS) // shifted |
25#define BR_QUES LSFT(BR_SLSH) // shifted ?
26#define BR_TRMA LSFT(KC_6) // shifted ¨ (dead key - trema accent)
27
28// On the ABNT2 the keypad comma and the keypad dot scancodes are switched
29// (presumably because in Brazil comma is used as the decimal separator)
30#define BR_KPDT KC_KP_COMMA // keypad .
31#define BR_KPCM KC_KP_DOT // keypad ,
32
33#define BR_1UP LALT(KC_1) // 1 superscript ¹ alt+1
34#define BR_2UP LALT(KC_2) // 2 superscript ² alt+2
35#define BR_3UP LALT(KC_3) // 3 superscript ³ alt+3
36#define BR_PND LALT(KC_4) // Pound sign £ alt+4
37#define BR_CENT LALT(KC_5) // Cent sign ¢ alt+5
38#define BR_NOT LALT(KC_6) // Not sign ¬ alt+6
39#define BR_SECT LALT(KC_EQL) // Section sign § alt+=
40#define BR_FORD LALT(BR_LBRC) // Feminine Ordinal Sign ª alt+[
41#define BR_MORD LALT(BR_RBRC) // Masculine Ordinal Sign º alt+]
42#define BR_DGRE LALT(BR_SLSH) // Degree sign ° alt+/
43
44#define BR_EURO LALT(KC_E) // Euro sign € alt+e
45#define BR_NDTD LALT(BR_TILD) // Non-dead key tilde ~ alt+~
46#define BR_NDAC LALT(BR_ACUT) // Non-dead key acute accent ´ alt+´
47#define BR_NDGV LALT(BR_QUOT) // Non-dead key grave accent ` alt+'
48#define BR_NDCR LALT(BR_CIRC) // Non-dead key circumflex accent ^ alt+^ (alt+shift+~)
49#define BR_NDTR LALT(BR_TRMA) // Non-dead key trema accent ¨ alt+¨ (alt+shift+6)
50
51// For 101-key keyboard layouts, the ABNT2 layout allows
52// the slash and question mark to be typed using alt+q and alt+w.
53// The shortcuts are provided here for completeness' sake,
54// but it's recommended to use BR_SLSH and BR_QUES instead
55#define BR_ASLS LALT(KC_Q)
56#define BR_AQST LALT(KC_W)
57
58#endif
diff --git a/quantum/keymap_extras/keymap_dvp.h b/quantum/keymap_extras/keymap_dvp.h
new file mode 100644
index 000000000..83f49a52b
--- /dev/null
+++ b/quantum/keymap_extras/keymap_dvp.h
@@ -0,0 +1,82 @@
1#ifndef KEYMAP_DVP_H
2#define KEYMAP_DVP_H
3
4#include "keymap.h"
5
6// Normal characters
7#define DP_DLR KC_GRV
8#define DP_AMPR KC_1
9#define DP_LBRC KC_2
10#define DP_LCBR KC_3
11#define DP_RCBR KC_4
12#define DP_LPRN KC_5
13#define DP_EQL KC_6
14#define DP_ASTR KC_7
15#define DP_RPRN KC_8
16#define DP_PLUS KC_9
17#define DP_RBRC KC_0
18#define DP_EXLM KC_MINS
19#define DP_HASH KC_EQL
20
21#define DP_SCLN KC_Q
22#define DP_COMM KC_W
23#define DP_DOT KC_E
24#define DP_P KC_R
25#define DP_Y KC_T
26#define DP_F KC_Y
27#define DP_G KC_U
28#define DP_C KC_I
29#define DP_R KC_O
30#define DP_L KC_P
31#define DP_SLSH KC_LBRC
32#define DP_AT KC_RBRC
33#define DP_BSLS KC_BSLS
34
35#define DP_A KC_A
36#define DP_O KC_S
37#define DP_E KC_D
38#define DP_U KC_F
39#define DP_I KC_G
40#define DP_D KC_H
41#define DP_H KC_J
42#define DP_T KC_K
43#define DP_N KC_L
44#define DP_S KC_SCLN
45#define DP_MINS KC_QUOT
46
47#define DP_QUOT KC_Z
48#define DP_Q KC_X
49#define DP_J KC_C
50#define DP_K KC_V
51#define DP_X KC_B
52#define DP_B KC_N
53#define DP_M KC_M
54#define DP_W KC_COMM
55#define DP_V KC_DOT
56#define DP_Z KC_SLSH
57
58// Shifted characters
59#define DP_TILD LSFT(DP_DLR)
60#define DP_PERC LSFT(DP_AMPR)
61#define DP_7 LSFT(DP_LBRC)
62#define DP_5 LSFT(DP_LCBR)
63#define DP_3 LSFT(DP_RCBR)
64#define DP_1 LSFT(DP_LPRN)
65#define DP_9 LSFT(DP_EQL)
66#define DP_0 LSFT(DP_ASTR)
67#define DP_2 LSFT(DP_RPRN)
68#define DP_4 LSFT(DP_PLUS)
69#define DP_6 LSFT(DP_RBRC)
70#define DP_8 LSFT(DP_EXLM)
71#define DP_GRV LSFT(DP_HASH)
72
73#define DP_COLN LSFT(DP_SCLN)
74#define DP_LABK LSFT(DP_COMM)
75#define DP_RABK LSFT(DP_DOT)
76#define DP_QUES LSFT(DP_SLSH)
77#define DP_CIRC LSFT(DP_AT)
78#define DP_PIPE LSFT(DP_BSLS)
79#define DP_UNDS LSFT(DP_MINS)
80#define DP_DQUO LSFT(DP_QUOT)
81
82#endif
diff --git a/quantum/light_ws2812.c b/quantum/light_ws2812.c
index d38dac4c6..497543339 100755
--- a/quantum/light_ws2812.c
+++ b/quantum/light_ws2812.c
@@ -152,11 +152,6 @@ void inline ws2812_setleds_pin(struct cRGB *ledarray, uint16_t leds, uint8_t pin
152// Setleds for SK6812RGBW 152// Setleds for SK6812RGBW
153void inline ws2812_setleds_rgbw(struct cRGBW *ledarray, uint16_t leds) 153void inline ws2812_setleds_rgbw(struct cRGBW *ledarray, uint16_t leds)
154{ 154{
155 // ws2812_DDRREG |= _BV(ws2812_pin); // Enable DDR
156 // new universal format (DDR)
157 _SFR_IO8((RGB_DI_PIN >> 4) + 1) |= _BV(RGB_DI_PIN & 0xF);
158
159 ws2812_sendarray_mask((uint8_t*)ledarray,leds<<2,_BV(RGB_DI_PIN & 0xF));
160 155
161 #ifdef RGBW_BB_TWI 156 #ifdef RGBW_BB_TWI
162 cli(); 157 cli();
@@ -169,14 +164,23 @@ void inline ws2812_setleds_rgbw(struct cRGBW *ledarray, uint16_t leds)
169 uint8_t * data = (uint8_t*)ledarray; 164 uint8_t * data = (uint8_t*)ledarray;
170 while (datlen--) { 165 while (datlen--) {
171 curbyte=*data++; 166 curbyte=*data++;
172 I2C_Write(curbyte % 0x10); 167 I2C_Write(curbyte);
173 } 168 }
174 I2C_Stop(); 169 I2C_Stop();
175 sei(); 170 sei();
171 #else
172 _delay_us(80);
176 #endif 173 #endif
177 174
178 175
179 _delay_us(80); 176 // ws2812_DDRREG |= _BV(ws2812_pin); // Enable DDR
177 // new universal format (DDR)
178 _SFR_IO8((RGB_DI_PIN >> 4) + 1) |= _BV(RGB_DI_PIN & 0xF);
179
180 ws2812_sendarray_mask((uint8_t*)ledarray,leds<<2,_BV(RGB_DI_PIN & 0xF));
181
182
183
180} 184}
181 185
182void ws2812_sendarray(uint8_t *data,uint16_t datlen) 186void ws2812_sendarray(uint8_t *data,uint16_t datlen)
@@ -258,7 +262,7 @@ void inline ws2812_sendarray_mask(uint8_t *data,uint16_t datlen,uint8_t maskhi)
258 cli(); 262 cli();
259 263
260 while (datlen--) { 264 while (datlen--) {
261 curbyte=(*data++) % 0x10; 265 curbyte=(*data++);
262 266
263 asm volatile( 267 asm volatile(
264 " ldi %0,8 \n\t" 268 " ldi %0,8 \n\t"
diff --git a/quantum/process_keycode/process_unicode.c b/quantum/process_keycode/process_unicode.c
index 6a30afe29..cd3a610b4 100644
--- a/quantum/process_keycode/process_unicode.c
+++ b/quantum/process_keycode/process_unicode.c
@@ -42,6 +42,11 @@ void unicode_input_start (void) {
42 register_code(KC_PPLS); 42 register_code(KC_PPLS);
43 unregister_code(KC_PPLS); 43 unregister_code(KC_PPLS);
44 break; 44 break;
45 case UC_WINC:
46 register_code(KC_RALT);
47 unregister_code(KC_RALT);
48 register_code(KC_U);
49 unregister_code(KC_U);
45 } 50 }
46 wait_ms(UNICODE_TYPE_DELAY); 51 wait_ms(UNICODE_TYPE_DELAY);
47} 52}
@@ -78,6 +83,52 @@ bool process_unicode(uint16_t keycode, keyrecord_t *record) {
78 return true; 83 return true;
79} 84}
80 85
86#ifdef UNICODEMAP_ENABLE
87__attribute__((weak))
88const uint32_t PROGMEM unicode_map[] = {
89};
90
91void register_hex32(uint32_t hex) {
92 uint8_t onzerostart = 1;
93 for(int i = 7; i >= 0; i--) {
94 if (i <= 3) {
95 onzerostart = 0;
96 }
97 uint8_t digit = ((hex >> (i*4)) & 0xF);
98 if (digit == 0) {
99 if (onzerostart == 0) {
100 register_code(hex_to_keycode(digit));
101 unregister_code(hex_to_keycode(digit));
102 }
103 } else {
104 register_code(hex_to_keycode(digit));
105 unregister_code(hex_to_keycode(digit));
106 onzerostart = 0;
107 }
108 }
109}
110
111__attribute__((weak))
112void unicode_map_input_error() {}
113
114bool process_unicode_map(uint16_t keycode, keyrecord_t *record) {
115 if ((keycode & QK_UNICODE_MAP) == QK_UNICODE_MAP && record->event.pressed) {
116 const uint32_t* map = unicode_map;
117 uint16_t index = keycode & 0x7FF;
118 uint32_t code = pgm_read_dword_far(&map[index]);
119 if ((code > 0xFFFF && input_mode == UC_OSX) || (code > 0xFFFFF && input_mode == UC_LNX)) {
120 // when character is out of range supported by the OS
121 unicode_map_input_error();
122 } else {
123 unicode_input_start();
124 register_hex32(code);
125 unicode_input_finish();
126 }
127 }
128 return true;
129}
130#endif
131
81#ifdef UCIS_ENABLE 132#ifdef UCIS_ENABLE
82qk_ucis_state_t qk_ucis_state; 133qk_ucis_state_t qk_ucis_state;
83 134
diff --git a/quantum/process_keycode/process_unicode.h b/quantum/process_keycode/process_unicode.h
index 27f8072ee..065eeb5f6 100644
--- a/quantum/process_keycode/process_unicode.h
+++ b/quantum/process_keycode/process_unicode.h
@@ -3,10 +3,11 @@
3 3
4#include "quantum.h" 4#include "quantum.h"
5 5
6#define UC_OSX 0 6#define UC_OSX 0 // Mac OS X
7#define UC_LNX 1 7#define UC_LNX 1 // Linux
8#define UC_WIN 2 8#define UC_WIN 2 // Windows 'HexNumpad'
9#define UC_BSD 3 9#define UC_BSD 3 // BSD (not implemented)
10#define UC_WINC 4 // WinCompose https://github.com/samhocevar/wincompose
10 11
11#ifndef UNICODE_TYPE_DELAY 12#ifndef UNICODE_TYPE_DELAY
12#define UNICODE_TYPE_DELAY 10 13#define UNICODE_TYPE_DELAY 10
@@ -20,6 +21,10 @@ void register_hex(uint16_t hex);
20 21
21bool process_unicode(uint16_t keycode, keyrecord_t *record); 22bool process_unicode(uint16_t keycode, keyrecord_t *record);
22 23
24#ifdef UNICODEMAP_ENABLE
25bool process_unicode_map(uint16_t keycode, keyrecord_t *record);
26#endif
27
23#ifdef UCIS_ENABLE 28#ifdef UCIS_ENABLE
24#ifndef UCIS_MAX_SYMBOL_LENGTH 29#ifndef UCIS_MAX_SYMBOL_LENGTH
25#define UCIS_MAX_SYMBOL_LENGTH 32 30#define UCIS_MAX_SYMBOL_LENGTH 32
diff --git a/quantum/quantum.c b/quantum/quantum.c
index 5fa5e66b3..b8a81a76b 100644
--- a/quantum/quantum.c
+++ b/quantum/quantum.c
@@ -131,6 +131,8 @@ bool process_record_quantum(keyrecord_t *record) {
131 #endif 131 #endif
132 #ifdef PRINTING_ENABLE 132 #ifdef PRINTING_ENABLE
133 process_printer(keycode, record) && 133 process_printer(keycode, record) &&
134 #ifdef UNICODEMAP_ENABLE
135 process_unicode_map(keycode, record) &&
134 #endif 136 #endif
135 true)) { 137 true)) {
136 return false; 138 return false;
diff --git a/quantum/rgblight.c b/quantum/rgblight.c
index 801ca1d0d..221a16402 100644
--- a/quantum/rgblight.c
+++ b/quantum/rgblight.c
@@ -6,24 +6,37 @@
6#include "rgblight.h" 6#include "rgblight.h"
7#include "debug.h" 7#include "debug.h"
8 8
9// Lightness curve using the CIE 1931 lightness formula
10//Generated by the python script provided in http://jared.geek.nz/2013/feb/linear-led-pwm
9const uint8_t DIM_CURVE[] PROGMEM = { 11const uint8_t DIM_CURVE[] PROGMEM = {
10 0, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 12 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
11 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 13 1, 1, 1, 1, 2, 2, 2, 2, 2, 2,
12 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 14 2, 2, 2, 3, 3, 3, 3, 3, 3, 3,
13 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 15 3, 4, 4, 4, 4, 4, 4, 5, 5, 5,
14 8, 8, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 11, 11, 11, 16 5, 5, 6, 6, 6, 6, 6, 7, 7, 7,
15 11, 11, 12, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 17 7, 8, 8, 8, 8, 9, 9, 9, 10, 10,
16 15, 15, 16, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 20, 18 10, 10, 11, 11, 11, 12, 12, 12, 13, 13,
17 20, 20, 21, 21, 22, 22, 22, 23, 23, 24, 24, 25, 25, 25, 26, 26, 19 13, 14, 14, 15, 15, 15, 16, 16, 17, 17,
18 27, 27, 28, 28, 29, 29, 30, 30, 31, 32, 32, 33, 33, 34, 35, 35, 20 17, 18, 18, 19, 19, 20, 20, 21, 21, 22,
19 36, 36, 37, 38, 38, 39, 40, 40, 41, 42, 43, 43, 44, 45, 46, 47, 21 22, 23, 23, 24, 24, 25, 25, 26, 26, 27,
20 48, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 22 28, 28, 29, 29, 30, 31, 31, 32, 32, 33,
21 63, 64, 65, 66, 68, 69, 70, 71, 73, 74, 75, 76, 78, 79, 81, 82, 23 34, 34, 35, 36, 37, 37, 38, 39, 39, 40,
22 83, 85, 86, 88, 90, 91, 93, 94, 96, 98, 99, 101, 103, 105, 107, 109, 24 41, 42, 43, 43, 44, 45, 46, 47, 47, 48,
23 110, 112, 114, 116, 118, 121, 123, 125, 127, 129, 132, 134, 136, 139, 141, 144, 25 49, 50, 51, 52, 53, 54, 54, 55, 56, 57,
24 146, 149, 151, 154, 157, 159, 162, 165, 168, 171, 174, 177, 180, 183, 186, 190, 26 58, 59, 60, 61, 62, 63, 64, 65, 66, 67,
25 193, 196, 200, 203, 207, 211, 214, 218, 222, 226, 230, 234, 238, 242, 248, 255 27 68, 70, 71, 72, 73, 74, 75, 76, 77, 79,
26}; 28 80, 81, 82, 83, 85, 86, 87, 88, 90, 91,
29 92, 94, 95, 96, 98, 99, 100, 102, 103, 105,
30 106, 108, 109, 110, 112, 113, 115, 116, 118, 120,
31 121, 123, 124, 126, 128, 129, 131, 132, 134, 136,
32 138, 139, 141, 143, 145, 146, 148, 150, 152, 154,
33 155, 157, 159, 161, 163, 165, 167, 169, 171, 173,
34 175, 177, 179, 181, 183, 185, 187, 189, 191, 193,
35 196, 198, 200, 202, 204, 207, 209, 211, 214, 216,
36 218, 220, 223, 225, 228, 230, 232, 235, 237, 240,
37 242, 245, 247, 250, 252, 255,
38 };
39
27const uint8_t RGBLED_BREATHING_TABLE[] PROGMEM = { 40const uint8_t RGBLED_BREATHING_TABLE[] PROGMEM = {
28 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 5, 5, 6, 7, 9, 41 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 5, 5, 6, 7, 9,
29 10, 11, 12, 14, 15, 17, 18, 20, 21, 23, 25, 27, 29, 31, 33, 35, 42 10, 11, 12, 14, 15, 17, 18, 20, 21, 23, 25, 27, 29, 31, 33, 35,
@@ -42,10 +55,16 @@ const uint8_t RGBLED_BREATHING_TABLE[] PROGMEM = {
42 37, 35, 33, 31, 29, 27, 25, 23, 21, 20, 18, 17, 15, 14, 12, 11, 55 37, 35, 33, 31, 29, 27, 25, 23, 21, 20, 18, 17, 15, 14, 12, 11,
43 10, 9, 7, 6, 5, 5, 4, 3, 2, 2, 1, 1, 1, 0, 0, 0 56 10, 9, 7, 6, 5, 5, 4, 3, 2, 2, 1, 1, 1, 0, 0, 0
44}; 57};
58
59__attribute__ ((weak))
45const uint8_t RGBLED_BREATHING_INTERVALS[] PROGMEM = {30, 20, 10, 5}; 60const uint8_t RGBLED_BREATHING_INTERVALS[] PROGMEM = {30, 20, 10, 5};
61__attribute__ ((weak))
46const uint8_t RGBLED_RAINBOW_MOOD_INTERVALS[] PROGMEM = {120, 60, 30}; 62const uint8_t RGBLED_RAINBOW_MOOD_INTERVALS[] PROGMEM = {120, 60, 30};
63__attribute__ ((weak))
47const uint8_t RGBLED_RAINBOW_SWIRL_INTERVALS[] PROGMEM = {100, 50, 20}; 64const uint8_t RGBLED_RAINBOW_SWIRL_INTERVALS[] PROGMEM = {100, 50, 20};
65__attribute__ ((weak))
48const uint8_t RGBLED_SNAKE_INTERVALS[] PROGMEM = {100, 50, 20}; 66const uint8_t RGBLED_SNAKE_INTERVALS[] PROGMEM = {100, 50, 20};
67__attribute__ ((weak))
49const uint8_t RGBLED_KNIGHT_INTERVALS[] PROGMEM = {100, 50, 20}; 68const uint8_t RGBLED_KNIGHT_INTERVALS[] PROGMEM = {100, 50, 20};
50 69
51rgblight_config_t rgblight_config; 70rgblight_config_t rgblight_config;
@@ -59,13 +78,8 @@ uint8_t rgblight_inited = 0;
59 78
60 79
61void sethsv(uint16_t hue, uint8_t sat, uint8_t val, struct cRGB *led1) { 80void sethsv(uint16_t hue, uint8_t sat, uint8_t val, struct cRGB *led1) {
62 // Convert hue, saturation, and value (HSV/HSB) to RGB. DIM_CURVE is used only
63 // on value and saturation (inverted). This looks the most natural.
64 uint8_t r = 0, g = 0, b = 0, base, color; 81 uint8_t r = 0, g = 0, b = 0, base, color;
65 82
66 val = pgm_read_byte(&DIM_CURVE[val]);
67 sat = 255 - pgm_read_byte(&DIM_CURVE[255 - sat]);
68
69 if (sat == 0) { // Acromatic color (gray). Hue doesn't mind. 83 if (sat == 0) { // Acromatic color (gray). Hue doesn't mind.
70 r = val; 84 r = val;
71 g = val; 85 g = val;
@@ -107,6 +121,9 @@ void sethsv(uint16_t hue, uint8_t sat, uint8_t val, struct cRGB *led1) {
107 break; 121 break;
108 } 122 }
109 } 123 }
124 r = pgm_read_byte(&DIM_CURVE[r]);
125 g = pgm_read_byte(&DIM_CURVE[g]);
126 b = pgm_read_byte(&DIM_CURVE[b]);
110 127
111 setrgb(r, g, b, led1); 128 setrgb(r, g, b, led1);
112} 129}
diff --git a/quantum/rgblight.h b/quantum/rgblight.h
index 2a712d8be..efc685f31 100644
--- a/quantum/rgblight.h
+++ b/quantum/rgblight.h
@@ -41,6 +41,12 @@
41#include "eeconfig.h" 41#include "eeconfig.h"
42#include "light_ws2812.h" 42#include "light_ws2812.h"
43 43
44extern const uint8_t RGBLED_BREATHING_INTERVALS[4] PROGMEM;
45extern const uint8_t RGBLED_RAINBOW_MOOD_INTERVALS[3] PROGMEM;
46extern const uint8_t RGBLED_RAINBOW_SWIRL_INTERVALS[3] PROGMEM;
47extern const uint8_t RGBLED_SNAKE_INTERVALS[3] PROGMEM;
48extern const uint8_t RGBLED_KNIGHT_INTERVALS[3] PROGMEM;
49
44typedef union { 50typedef union {
45 uint32_t raw; 51 uint32_t raw;
46 struct { 52 struct {
diff --git a/quantum/variable_trace.c b/quantum/variable_trace.c
new file mode 100644
index 000000000..de580244c
--- /dev/null
+++ b/quantum/variable_trace.c
@@ -0,0 +1,110 @@
1#include "variable_trace.h"
2#include <stddef.h>
3#include <string.h>
4
5#ifdef NO_PRINT
6#error "You need undef NO_PRINT to use the variable trace feature"
7#endif
8
9#ifndef CONSOLE_ENABLE
10#error "The console needs to be enabled in the makefile to use the variable trace feature"
11#endif
12
13
14#define NUM_TRACED_VARIABLES 1
15#ifndef MAX_VARIABLE_TRACE_SIZE
16 #define MAX_VARIABLE_TRACE_SIZE 4
17#endif
18
19typedef struct {
20 const char* name;
21 void* addr;
22 unsigned size;
23 const char* func;
24 int line;
25 uint8_t last_value[MAX_VARIABLE_TRACE_SIZE];
26
27} traced_variable_t;
28
29static traced_variable_t traced_variables[NUM_TRACED_VARIABLES];
30
31void add_traced_variable(const char* name, void* addr, unsigned size, const char* func, int line) {
32 verify_traced_variables(func, line);
33 if (size > MAX_VARIABLE_TRACE_SIZE) {
34#if defined(__AVR__)
35 xprintf("Traced variable \"%S\" exceeds the maximum size %d\n", name, size);
36#else
37 xprintf("Traced variable \"%s\" exceeds the maximum size %d\n", name, size);
38#endif
39 size = MAX_VARIABLE_TRACE_SIZE;
40 }
41 int index = -1;
42 for (int i = 0; i < NUM_TRACED_VARIABLES; i++) {
43 if (index == -1 && traced_variables[i].addr == NULL){
44 index = i;
45 }
46 else if (strcmp_P(name, traced_variables[i].name)==0) {
47 index = i;
48 break;
49 }
50 }
51
52 if (index == -1) {
53 xprintf("You can only trace %d variables at the same time\n", NUM_TRACED_VARIABLES);
54 return;
55 }
56
57 traced_variable_t* t = &traced_variables[index];
58 t->name = name;
59 t->addr = addr;
60 t->size = size;
61 t->func = func;
62 t->line = line;
63 memcpy(&t->last_value[0], addr, size);
64
65}
66
67void remove_traced_variable(const char* name, const char* func, int line) {
68 verify_traced_variables(func, line);
69 for (int i = 0; i < NUM_TRACED_VARIABLES; i++) {
70 if (strcmp_P(name, traced_variables[i].name)==0) {
71 traced_variables[i].name = 0;
72 traced_variables[i].addr = NULL;
73 break;
74 }
75 }
76}
77
78void verify_traced_variables(const char* func, int line) {
79 for (int i = 0; i < NUM_TRACED_VARIABLES; i++) {
80 traced_variable_t* t = &traced_variables[i];
81 if (t->addr != NULL && t->name != NULL) {
82 if (memcmp(t->last_value, t->addr, t->size)!=0){
83#if defined(__AVR__)
84 xprintf("Traced variable \"%S\" has been modified\n", t->name);
85 xprintf("Between %S:%d\n", t->func, t->line);
86 xprintf("And %S:%d\n", func, line);
87
88#else
89 xprintf("Traced variable \"%s\" has been modified\n", t->name);
90 xprintf("Between %s:%d\n", t->func, t->line);
91 xprintf("And %s:%d\n", func, line);
92#endif
93 xprintf("Previous value ");
94 for (int j=0; j<t->size;j++) {
95 print_hex8(t->last_value[j]);
96 }
97 xprintf("\nNew value ");
98 uint8_t* addr = (uint8_t*)(t->addr);
99 for (int j=0; j<t->size;j++) {
100 print_hex8(addr[j]);
101 }
102 xprintf("\n");
103 memcpy(t->last_value, addr, t->size);
104 }
105 }
106
107 t->func = func;
108 t->line = line;
109 }
110}
diff --git a/quantum/variable_trace.h b/quantum/variable_trace.h
new file mode 100644
index 000000000..46bd82786
--- /dev/null
+++ b/quantum/variable_trace.h
@@ -0,0 +1,34 @@
1#ifndef VARIABLE_TRACE_H
2#define VARIABLE_TRACE_H
3
4// For more information about the variable tracing see the readme.
5
6#include "print.h"
7
8#ifdef NUM_TRACED_VARIABLES
9
10// Start tracing a variable at the memory address addr
11// The name can be anything and is used only for reporting
12// The size should usually be the same size as the variable you are interested in
13#define ADD_TRACED_VARIABLE(name, addr, size) \
14 add_traced_variable(PSTR(name), (void*)addr, size, PSTR(__FILE__), __LINE__)
15
16// Stop tracing the variable with the given name
17#define REMOVE_TRACED_VARIABLE(name) remove_traced_variable(PSTR(name), PSTR(__FILE__), __LINE__)
18
19// Call to get messages when the variable has been changed
20#define VERIFY_TRACED_VARIABLES() verify_traced_variables(PSTR(__FILE__), __LINE__)
21
22#else
23
24#define ADD_TRACED_VARIABLE(name, addr, size)
25#define REMOVE_TRACED_VARIABLE(name)
26#define VERIFY_TRACED_VARIABLES()
27
28#endif
29
30// Don't call directly, use the macros instead
31void add_traced_variable(const char* name, void* addr, unsigned size, const char* func, int line);
32void remove_traced_variable(const char* name, const char* func, int line);
33void verify_traced_variables(const char* func, int line);
34#endif