aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--keyboards/handwired/d48/README.md87
-rw-r--r--keyboards/handwired/d48/config.h77
-rw-r--r--keyboards/handwired/d48/d48.c1
-rw-r--r--keyboards/handwired/d48/d48.h19
-rw-r--r--keyboards/handwired/d48/ds1307.c21
-rw-r--r--keyboards/handwired/d48/ds1307.h6
-rw-r--r--keyboards/handwired/d48/glcdfont_d48.c231
-rw-r--r--keyboards/handwired/d48/keymaps/anderson/keymap.c340
-rw-r--r--keyboards/handwired/d48/keymaps/anderson/lightmode.c44
-rw-r--r--keyboards/handwired/d48/keymaps/anderson/lightmode.h12
-rw-r--r--keyboards/handwired/d48/keymaps/anderson/rules.mk2
-rw-r--r--keyboards/handwired/d48/keymaps/default/keymap.c285
-rw-r--r--keyboards/handwired/d48/rules.mk22
-rw-r--r--keyboards/handwired/d48/taphold.c29
-rw-r--r--keyboards/handwired/d48/taphold.h25
-rw-r--r--users/anderson/dmc12.c46
-rw-r--r--users/anderson/dmc12.h9
-rw-r--r--users/anderson/seq.c38
-rw-r--r--users/anderson/seq.h14
-rw-r--r--users/anderson/smoothled.c34
-rw-r--r--users/anderson/smoothled.h6
21 files changed, 1348 insertions, 0 deletions
diff --git a/keyboards/handwired/d48/README.md b/keyboards/handwired/d48/README.md
new file mode 100644
index 000000000..a20b8a425
--- /dev/null
+++ b/keyboards/handwired/d48/README.md
@@ -0,0 +1,87 @@
1# D48
2
3![Proton C based handwired 40% keyboard](https://i.imgur.com/2wCYuno.jpg)
4
5A Proton C based handwired 48 key keyboard with 2 rotary encoders, I2C OLED, WS2812 strip, buzzer & clock!
6
7- Keyboard Maintainer: Andrew Dunai
8- Hardware Supported: Proton C handwired
9
10Make example for this keyboard (after setting up your build environment):
11
12 make handwired/d48:default
13
14## Details
15
16- Proton C based handwired keyboard
17- 2x custom 1.25mm stainless steel plates
18- Kailh Choc White (clicky)
19- 2x rotary encoders
20- 0.91" 128x32 I<sup>2</sup>C OLED
21- Small buzzer mounted inside (still waiting for the AST1109MLTRQ boys)
22- WS2812 strip (14 LEDs)
23- DS1307 I<sup>2</sup>C module real-time clock
24
25Build process: [album](https://imgur.com/gallery/zZZGdDw)
26
27## Pinout
28
29![D48 pinout](https://imgur.com/QoStCvD.jpg)
30
31## Challenges
32
33I'm very happy with the result, but at some point Proton C was driving me nuts.
34
35I did a lot of trial and error during assembly & programming.
36There were a lot of *yet* undocumented caveats,
37so I'll outline them here so that you guys can avoid the same issues I had.
38
39## Matrix & encoders
40
41Although this is a 48-key board with a 12-col & 4-row matrix, I've decided to add an extra row above the first one
42to make my matrix 12x5 and wire encoders' push buttons as 2 extra keys, thus making it a total of 50 (12x4 + 2 encoders).
43I used 2 columns (9 & 12) for those buttons.
44
45So, a first row actually has 2 buttons on columns 9 & 12 (because encoders are located near those columns).
46Encoders' push buttons are also configured via QMK's keymap.
47
48Check out the `d48.h` & `config.h` for pins used & keymap macro definition.
49
50## I<sup>2</sup>C/OLED
51
52Most of the stuff worked out of the box, except me choosing the right pins for my OLED.
53
54On the Proton C pinout, there are 3 labels for I<sup>2</sup>C and for some reason
55there are 2 pairs of SDA/SCL for I<sup>2</sup>C<sup>1</sup> channel: `B8`/`B9` (rear left side) and `B6`/`B7` (rear right side).
56I'm not sure if this is a mistake or if I was doing something wrong. So initially I picked `B8`/`B9`
57which were not working. When I switched to B6/B7, things worked like a charm.
58Later I used B9 for matrix row. No issues so far.
59
60Oh, and by the way, while using `B8`/`B9`, keyboard was sometimes *swallowing* quick keypresses.
61I believe this was due to I(2)C timeouts (because incorrect pins were used for OLED).
62
63## Buzzer
64
65It turns out once you switch on `AUDIO_ENABLE`, you cannot use A4 & A5 because they interfere with the buzzer.
66My guess is that buzzer uses DAC channels (not sure why both).
67
68I couldn't find this in documentation. Honestly, Proton C has almost zero documentation and this was
69the biggest challenge. Anyway, apart from almost going crazy from those challenges, I really liked it!
70
71## RGB
72
73I used pin `A15` for my WS28128 RGB strip.
74
75## D1307 real-time clock
76
77Connecting DS1307 RTC was a piece of cake: same I<sup>2</sup> pins as OLED (SDA/SCL), GND to GND and power to Proton C VUSB pin (5v).
78
79## Other issues
80
81- `B5` could not be used for matrix.
82- `TAP_CODE_DELAY` had to be increased to 10 to fix `tap_code(KC_VOLU/KC_VOLD)` calls being swallowed in encoder callback.
83- Be extremely attentive about the pinout: keep in mind that **the official Proton C pinout displays the rear of the board, not the front.** Being used to front pinouts, I ended up soldering entire matrix to the wrong side, so I had to desolder every wire and connect it to the opposite side.
84
85## Conclusion
86
87I had a lot of fun. The layout was inspired by the Planck THK. Feel free to ask any questions!
diff --git a/keyboards/handwired/d48/config.h b/keyboards/handwired/d48/config.h
new file mode 100644
index 000000000..9c2344299
--- /dev/null
+++ b/keyboards/handwired/d48/config.h
@@ -0,0 +1,77 @@
1#pragma once
2
3#include "config_common.h"
4
5/* USB Device descriptor parameter */
6#define VENDOR_ID 0xFEED
7#define PRODUCT_ID 0x6060
8#define DEVICE_VER 0x0001
9#define MANUFACTURER Andrew Dunai
10#define PRODUCT D48
11
12/* Key matrix size */
13#define MATRIX_ROWS 5
14#define MATRIX_COLS 12
15
16/* Key matrix pins */
17#define MATRIX_ROW_PINS { B8, B9, B1, B2, B4 }
18
19#define MATRIX_COL_PINS { A2, B0, A7, A8, A13, A14, B12, B11, B10, B15, B14, B13 }
20#define UNUSED_PINS
21
22/* COL2ROW or ROW2COL */
23#define DIODE_DIRECTION COL2ROW
24
25/* Set 0 if debouncing isn't needed */
26// #define DEBOUNCE 5
27
28/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
29// #define LOCKING_SUPPORT_ENABLE
30
31/* Locking resynchronize hack */
32// #define LOCKING_RESYNC_ENABLE
33
34/* prevent stuck modifiers */
35// #define PREVENT_STUCK_MODIFIERS
36
37/* RGB Underglow */
38#ifdef RGBLIGHT_ENABLE
39#define RGB_DI_PIN A15
40#define RGBLED_NUM 14
41#define RGBLIGHT_HUE_STEP 8
42#define RGBLIGHT_SAT_STEP 8
43#define RGBLIGHT_VAL_STEP 8
44#define RGBLIGHT_ANIMATIONS
45#endif
46
47/* Audio */
48#ifdef AUDIO_ENABLE
49#define STARTUP_SONG_DOOM SONG(E1M1_DOOM)
50#define STARTUP_SONG SONG( \
51 Q__NOTE(_E6), \
52 Q__NOTE(_A6), \
53 H__NOTE(_E7), \
54 Q__NOTE(_E6), \
55 Q__NOTE(_E7) \
56)
57#endif
58
59/* Encoders */
60#define ENCODERS_PAD_A { B3, A0 }
61#define ENCODERS_PAD_B { A6, A1 }
62/* #define ENCODER_RESOLUTION 4 */
63
64/* OLED */
65#define OLED_FONT_H "glcdfont_d48.c"
66#define OLED_TIMEOUT 0
67// #define OLED_SCROLL_TIMEOUT 1000
68
69/* Taps (encoder tap_code) */
70#define TAP_CODE_DELAY 10
71
72/* I2C */
73//#define I2C1_DUTY_CYCLE FAST_DUTY_CYCLE_2
74//#define PAL_MODE_STM32_ALTERNATE_OPENDRAIN (PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN)
75
76/* DS1307 */
77#define DS1307_ADDR (0x68 << 1)
diff --git a/keyboards/handwired/d48/d48.c b/keyboards/handwired/d48/d48.c
new file mode 100644
index 000000000..3cc2097bf
--- /dev/null
+++ b/keyboards/handwired/d48/d48.c
@@ -0,0 +1 @@
#include "d48.h"
diff --git a/keyboards/handwired/d48/d48.h b/keyboards/handwired/d48/d48.h
new file mode 100644
index 000000000..b698ca187
--- /dev/null
+++ b/keyboards/handwired/d48/d48.h
@@ -0,0 +1,19 @@
1#pragma once
2
3#include "quantum.h"
4
5#define ___ KC_NO
6
7#define LAYOUT( \
8 K08, K0B, \
9 K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, \
10 K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, \
11 K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, \
12 K40, K41, K42, K43, K44, K45, K46, K47, K48, K49, K4A, K4B \
13) { \
14 { ___, ___, ___, ___, ___, ___, ___, ___, K08, ___, ___, K0B }, \
15 { K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B }, \
16 { K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B }, \
17 { K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B }, \
18 { K40, K41, K42, K43, K44, K45, K46, K47, K48, K49, K4A, K4B } \
19}
diff --git a/keyboards/handwired/d48/ds1307.c b/keyboards/handwired/d48/ds1307.c
new file mode 100644
index 000000000..f6b57d50d
--- /dev/null
+++ b/keyboards/handwired/d48/ds1307.c
@@ -0,0 +1,21 @@
1#include "ds1307.h"
2#include "i2c_master.h"
3
4void ds1307_set_time(uint8_t h, uint8_t m, uint8_t s) {
5 uint8_t data[] = {
6 ((s % 10) | ((s / 10) << 4)) & 0x7F,
7 ((m % 10) | ((m / 10) << 4)) & 0x7F,
8 ((h % 10) | ((h / 10) << 4)) & 0x3F,
9 0, 0, 0, 0, 0
10 }; // 24-hour mode
11 i2c_writeReg(DS1307_ADDR, 0, data, 8, 100);
12}
13
14void ds1307_get_time(uint8_t *h, uint8_t *m, uint8_t *s) {
15 uint8_t data[3];
16 i2c_readReg(DS1307_ADDR, 0, data, 3, 100);
17 i2c_stop();
18 *s = (data[0] & 0b1111) + ((data[0] & 0b1110000) >> 4) * 10;
19 *m = (data[1] & 0b1111) + ((data[1] & 0b1110000) >> 4) * 10;
20 *h = (data[2] & 0b1111) + ((data[2] & 0b0110000) >> 4) * 10;
21}
diff --git a/keyboards/handwired/d48/ds1307.h b/keyboards/handwired/d48/ds1307.h
new file mode 100644
index 000000000..6f76db250
--- /dev/null
+++ b/keyboards/handwired/d48/ds1307.h
@@ -0,0 +1,6 @@
1#pragma once
2
3#include <stdint.h>
4
5void ds1307_set_time(uint8_t h, uint8_t m, uint8_t s);
6void ds1307_get_time(uint8_t *h, uint8_t *m, uint8_t *s);
diff --git a/keyboards/handwired/d48/glcdfont_d48.c b/keyboards/handwired/d48/glcdfont_d48.c
new file mode 100644
index 000000000..19063b00c
--- /dev/null
+++ b/keyboards/handwired/d48/glcdfont_d48.c
@@ -0,0 +1,231 @@
1#include "progmem.h"
2
3// Helidox 8x6 font with QMK Firmware Logo
4// Online editor: http://teripom.x0.com/
5
6static const unsigned char font[] PROGMEM = {
7 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8 0x3E, 0x5B, 0x4F, 0x5B, 0x3E, 0x00,
9 0x3E, 0x6B, 0x4F, 0x6B, 0x3E, 0x00,
10 0x1C, 0x3E, 0x7C, 0x3E, 0x1C, 0x00,
11 0x18, 0x3C, 0x7E, 0x3C, 0x18, 0x00,
12 0x1C, 0x57, 0x7D, 0x57, 0x1C, 0x00,
13 0x1C, 0x5E, 0x7F, 0x5E, 0x1C, 0x00,
14 0x00, 0x00, 0x08, 0x08, 0x00, 0x00,
15 0xFF, 0xE7, 0xC3, 0xE7, 0xFF, 0x00,
16 0x00, 0x18, 0x24, 0x18, 0x00, 0x00,
17 0xFF, 0xE7, 0xDB, 0xE7, 0xFF, 0x00,
18 0x30, 0x48, 0x3A, 0x06, 0x0E, 0x00,
19 0x26, 0x29, 0x79, 0x29, 0x26, 0x00,
20 0x40, 0x7F, 0x05, 0x05, 0x07, 0x00,
21 0x40, 0x7F, 0x05, 0x25, 0x3F, 0x00,
22 0x5A, 0x3C, 0xE7, 0x3C, 0x5A, 0x00,
23 0x7F, 0x3E, 0x1C, 0x1C, 0x08, 0x00,
24 0x08, 0x1C, 0x1C, 0x3E, 0x7F, 0x00,
25 0x14, 0x22, 0x7F, 0x22, 0x14, 0x00,
26 0x5F, 0x5F, 0x00, 0x5F, 0x5F, 0x00,
27 0x06, 0x09, 0x7F, 0x01, 0x7F, 0x00,
28 0x00, 0x66, 0x89, 0x95, 0x6A, 0x00,
29 0x60, 0x60, 0x60, 0x60, 0x60, 0x00,
30 0x94, 0xA2, 0xFF, 0xA2, 0x94, 0x00,
31 0x08, 0x04, 0x7E, 0x04, 0x08, 0x00,
32 0x10, 0x20, 0x7E, 0x20, 0x10, 0x00,
33 0x08, 0x08, 0x2A, 0x1C, 0x08, 0x00,
34 0x08, 0x1C, 0x2A, 0x08, 0x08, 0x00,
35 0x1E, 0x10, 0x10, 0x10, 0x10, 0x00,
36 0x0C, 0x1E, 0x0C, 0x1E, 0x0C, 0x00,
37 0x30, 0x38, 0x3E, 0x38, 0x30, 0x00,
38 0x06, 0x0E, 0x3E, 0x0E, 0x06, 0x00,
39 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
40 0x00, 0x00, 0x5F, 0x00, 0x00, 0x00,
41 0x00, 0x07, 0x00, 0x07, 0x00, 0x00,
42 0x14, 0x7F, 0x14, 0x7F, 0x14, 0x00,
43 0x24, 0x2A, 0x7F, 0x2A, 0x12, 0x00,
44 0x23, 0x13, 0x08, 0x64, 0x62, 0x00,
45 0x36, 0x49, 0x56, 0x20, 0x50, 0x00,
46 0x00, 0x08, 0x07, 0x03, 0x00, 0x00,
47 0x00, 0x1C, 0x22, 0x41, 0x00, 0x00,
48 0x00, 0x41, 0x22, 0x1C, 0x00, 0x00,
49 0x2A, 0x1C, 0x7F, 0x1C, 0x2A, 0x00,
50 0x08, 0x08, 0x3E, 0x08, 0x08, 0x00,
51 0x00, 0x80, 0x70, 0x30, 0x00, 0x00,
52 0x08, 0x08, 0x08, 0x08, 0x08, 0x00,
53 0x00, 0x00, 0x60, 0x60, 0x00, 0x00,
54 0x20, 0x10, 0x08, 0x04, 0x02, 0x00,
55 0x3E, 0x51, 0x49, 0x45, 0x3E, 0x00,
56 0x00, 0x42, 0x7F, 0x40, 0x00, 0x00,
57 0x72, 0x49, 0x49, 0x49, 0x46, 0x00,
58 0x21, 0x41, 0x49, 0x4D, 0x33, 0x00,
59 0x18, 0x14, 0x12, 0x7F, 0x10, 0x00,
60 0x27, 0x45, 0x45, 0x45, 0x39, 0x00,
61 0x3C, 0x4A, 0x49, 0x49, 0x31, 0x00,
62 0x41, 0x21, 0x11, 0x09, 0x07, 0x00,
63 0x36, 0x49, 0x49, 0x49, 0x36, 0x00,
64 0x46, 0x49, 0x49, 0x29, 0x1E, 0x00,
65 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
66 0x00, 0x40, 0x34, 0x00, 0x00, 0x00,
67 0x00, 0x08, 0x14, 0x22, 0x41, 0x00,
68 0x14, 0x14, 0x14, 0x14, 0x14, 0x00,
69 0x00, 0x41, 0x22, 0x14, 0x08, 0x00,
70 0x02, 0x01, 0x59, 0x09, 0x06, 0x00,
71 0x3E, 0x41, 0x5D, 0x59, 0x4E, 0x00,
72 0x7C, 0x12, 0x11, 0x12, 0x7C, 0x00,
73 0x7F, 0x49, 0x49, 0x49, 0x36, 0x00,
74 0x3E, 0x41, 0x41, 0x41, 0x22, 0x00,
75 0x7F, 0x41, 0x41, 0x41, 0x3E, 0x00,
76 0x7F, 0x49, 0x49, 0x49, 0x41, 0x00,
77 0x7F, 0x09, 0x09, 0x09, 0x01, 0x00,
78 0x3E, 0x41, 0x41, 0x51, 0x73, 0x00,
79 0x7F, 0x08, 0x08, 0x08, 0x7F, 0x00,
80 0x00, 0x41, 0x7F, 0x41, 0x00, 0x00,
81 0x20, 0x40, 0x41, 0x3F, 0x01, 0x00,
82 0x7F, 0x08, 0x14, 0x22, 0x41, 0x00,
83 0x7F, 0x40, 0x40, 0x40, 0x40, 0x00,
84 0x7F, 0x02, 0x1C, 0x02, 0x7F, 0x00,
85 0x7F, 0x04, 0x08, 0x10, 0x7F, 0x00,
86 0x3E, 0x41, 0x41, 0x41, 0x3E, 0x00,
87 0x7F, 0x09, 0x09, 0x09, 0x06, 0x00,
88 0x3E, 0x41, 0x51, 0x21, 0x5E, 0x00,
89 0x7F, 0x09, 0x19, 0x29, 0x46, 0x00,
90 0x26, 0x49, 0x49, 0x49, 0x32, 0x00,
91 0x03, 0x01, 0x7F, 0x01, 0x03, 0x00,
92 0x3F, 0x40, 0x40, 0x40, 0x3F, 0x00,
93 0x1F, 0x20, 0x40, 0x20, 0x1F, 0x00,
94 0x3F, 0x40, 0x38, 0x40, 0x3F, 0x00,
95 0x63, 0x14, 0x08, 0x14, 0x63, 0x00,
96 0x03, 0x04, 0x78, 0x04, 0x03, 0x00,
97 0x61, 0x59, 0x49, 0x4D, 0x43, 0x00,
98 0x00, 0x7F, 0x41, 0x41, 0x41, 0x00,
99 0x02, 0x04, 0x08, 0x10, 0x20, 0x00,
100 0x00, 0x41, 0x41, 0x41, 0x7F, 0x00,
101 0x04, 0x02, 0x01, 0x02, 0x04, 0x00,
102 0x40, 0x40, 0x40, 0x40, 0x40, 0x00,
103 0x00, 0x03, 0x07, 0x08, 0x00, 0x00,
104 0x20, 0x54, 0x54, 0x78, 0x40, 0x00,
105 0x7F, 0x28, 0x44, 0x44, 0x38, 0x00,
106 0x38, 0x44, 0x44, 0x44, 0x28, 0x00,
107 0x38, 0x44, 0x44, 0x28, 0x7F, 0x00,
108 0x38, 0x54, 0x54, 0x54, 0x18, 0x00,
109 0x00, 0x08, 0x7E, 0x09, 0x02, 0x00,
110 0x18, 0xA4, 0xA4, 0x9C, 0x78, 0x00,
111 0x7F, 0x08, 0x04, 0x04, 0x78, 0x00,
112 0x00, 0x44, 0x7D, 0x40, 0x00, 0x00,
113 0x20, 0x40, 0x40, 0x3D, 0x00, 0x00,
114 0x7F, 0x10, 0x28, 0x44, 0x00, 0x00,
115 0x00, 0x41, 0x7F, 0x40, 0x00, 0x00,
116 0x7C, 0x04, 0x78, 0x04, 0x78, 0x00,
117 0x7C, 0x08, 0x04, 0x04, 0x78, 0x00,
118 0x38, 0x44, 0x44, 0x44, 0x38, 0x00,
119 0xFC, 0x18, 0x24, 0x24, 0x18, 0x00,
120 0x18, 0x24, 0x24, 0x18, 0xFC, 0x00,
121 0x7C, 0x08, 0x04, 0x04, 0x08, 0x00,
122 0x48, 0x54, 0x54, 0x54, 0x24, 0x00,
123 0x04, 0x04, 0x3F, 0x44, 0x24, 0x00,
124 0x3C, 0x40, 0x40, 0x20, 0x7C, 0x00,
125 0x1C, 0x20, 0x40, 0x20, 0x1C, 0x00,
126 0x3C, 0x40, 0x30, 0x40, 0x3C, 0x00,
127 0x44, 0x28, 0x10, 0x28, 0x44, 0x00,
128 0x4C, 0x90, 0x90, 0x90, 0x7C, 0x00,
129 0x44, 0x64, 0x54, 0x4C, 0x44, 0x00,
130 0x00, 0x08, 0x36, 0x41, 0x00, 0x00,
131 0x00, 0x00, 0x77, 0x00, 0x00, 0x00,
132 0x00, 0x41, 0x36, 0x08, 0x00, 0x00,
133 0x02, 0x01, 0x02, 0x04, 0x02, 0x00,
134 0x3C, 0x26, 0x23, 0x26, 0x3C, 0x00,
135 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
136 0x00, 0x00, 0x60, 0x70, 0x78, 0x3C,
137 0x1E, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
138 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
139 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
140 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
141 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0,
142 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
143 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00,
144 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
145 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
146 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x07,
147 0x07, 0x07, 0x07, 0x07, 0x07, 0x0F,
148 0x1F, 0xFE, 0xFE, 0xF8, 0x00, 0x00,
149 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
150 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
151 0x00, 0xF0, 0xFC, 0xFE, 0xFE, 0x3F,
152 0x1F, 0x0F, 0x0F, 0x0F, 0x0F, 0x9F,
153 0xFF, 0xFE, 0xFE, 0xFC, 0xF0, 0x00,
154 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
155 0x3E, 0x22, 0x22, 0x00, 0x02, 0x3E,
156 0x02, 0x00, 0x3E, 0x20, 0x20, 0x00,
157 0x00, 0x3C, 0x0A, 0x3C, 0x00, 0x3E,
158 0x20, 0x20, 0x02, 0x3E, 0x02, 0x00,
159 0x00, 0x1C, 0x22, 0x32, 0x00, 0x1E,
160 0x20, 0x20, 0x1E, 0x00, 0x3E, 0x00,
161 0x00, 0x2C, 0x2A, 0x1A, 0x00, 0x3E,
162 0x0A, 0x02, 0x00, 0x02, 0x3E, 0x02,
163 0x00, 0x00, 0x08, 0x08, 0x08, 0x08,
164 0x08, 0x08, 0x08, 0x00, 0x00, 0x00,
165 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
166 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
167 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
168 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
169 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
170 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
171 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
172 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
173 0x00, 0x00, 0xC0, 0xF8, 0xFF, 0xFF,
174 0xFF, 0xE7, 0xE0, 0xE0, 0xE7, 0xFF,
175 0xFF, 0xFF, 0xF8, 0xC0, 0x00, 0x00,
176 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
177 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
178 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3C,
179 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x7E,
180 0xFF, 0xE7, 0xE7, 0x81, 0x00, 0x00,
181 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
182 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
183 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0,
184 0xF0, 0xF8, 0x7C, 0x3E, 0x1F, 0x0F,
185 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
186 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
187 0x00, 0x00, 0x22, 0x22, 0x00, 0x00,
188 0x0F, 0x0F, 0x2F, 0x2F, 0x0F, 0x0F,
189 0xF0, 0xF0, 0xF2, 0xF2, 0xF0, 0xF0,
190 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
191 0x00, 0x00, 0x22, 0x22, 0x00, 0xFF,
192 0x0F, 0x0F, 0x2F, 0x2F, 0x0F, 0xFF,
193 0xF0, 0xF0, 0xF2, 0xF2, 0xF0, 0xFF,
194 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
195 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
196 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
197 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
198 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
199 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
200 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
201 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
202 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
203 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
204 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
205 0xF0, 0xFE, 0xFF, 0xFF, 0x0F, 0x01,
206 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
207 0x01, 0x0F, 0xFF, 0xFF, 0xFE, 0xF0,
208 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
209 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
210 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0,
211 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xF0,
212 0xF8, 0x7F, 0x7F, 0x1F, 0x00, 0x00,
213 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
214 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
215 0x00, 0x0F, 0x3F, 0x7F, 0x7F, 0xFF,
216 0xF9, 0xF0, 0xF0, 0xF0, 0xF0, 0xF8,
217 0xFC, 0x7F, 0x7F, 0x3F, 0x0F, 0x00,
218 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
219 0xFF, 0x11, 0x11, 0x11, 0x11, 0x11,
220 0xFF, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
221 0xFF, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1,
222 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
223 0xFF, 0x11, 0x11, 0x11, 0x11, 0x11,
224 0xFF, 0x11, 0x11, 0x11, 0x11, 0x11,
225 0xFF, 0x11, 0x11, 0x11, 0x11, 0x11,
226 0xFF, 0x11, 0x11, 0x11, 0x11, 0x11,
227 0xFF, 0x11, 0x11, 0x11, 0x11, 0x11,
228 0xFF, 0x11, 0x11, 0x11, 0x11, 0x11,
229 0xFF, 0x11, 0x11, 0x11, 0x11, 0x11,
230 0xFF, 0x11, 0x11, 0x11, 0x11, 0x11,
231};
diff --git a/keyboards/handwired/d48/keymaps/anderson/keymap.c b/keyboards/handwired/d48/keymaps/anderson/keymap.c
new file mode 100644
index 000000000..25837a359
--- /dev/null
+++ b/keyboards/handwired/d48/keymaps/anderson/keymap.c
@@ -0,0 +1,340 @@
1#include QMK_KEYBOARD_H
2#include "taphold.h"
3#include "seq.h"
4#include "ds1307.h"
5#include "lightmode.h"
6#include <stdio.h>
7
8/* Note: don't forget there's some more code in qmk_firmware/users/anderson dir */
9
10#define _MAIN 0
11#define _ALPHA 1
12#define _BETA 2
13
14enum custom_keycodes {
15 KC_MAIN = SAFE_RANGE,
16 KC_ALPHA,
17 KC_BETA,
18#ifdef LIGHTMODE_ENABLE
19 KC_LIGHT_MODE,
20#endif
21 KC_SEQ,
22 KC_SET_TIME,
23};
24#ifdef LIGHTMODE_ENABLE
25#endif
26
27/* TapHold is my own implementation of the `LT` macro. It's processed in `process_record_user()`. */
28#define TAPHOLD_CONFIG_SIZE 3
29taphold_t taphold_config[TAPHOLD_CONFIG_SIZE] = {
30 {.key=KC_ALPHA, .mode=TAPHOLD_LAYER, .shortAction=KC_ESC, .longAction=_ALPHA},
31 {.key=KC_BETA, .mode=TAPHOLD_LAYER, .shortAction=KC_EQL, .longAction=_BETA},
32 {.key=KC_RCTRL, .mode=TAPHOLD_MOD, .shortAction=KC_MINS, .longAction=KC_LCTRL},
33};
34uint16_t taphold_config_size = TAPHOLD_CONFIG_SIZE;
35uint32_t taphold_timeout = 90;
36
37/* Seq is implementation of unicode macros similar to UCIS, but with unicode strings. */
38#define SEQ_CONFIG_SIZE 3
39seq_t seq_config[SEQ_CONFIG_SIZE] = {
40 {.sequence="temp", .result="42°C"},
41 {.sequence="table", .result="┳━━┳"},
42 {.sequence="shrug", .result="¯\\_(ツ)_/¯"}
43};
44uint16_t seq_config_size = SEQ_CONFIG_SIZE;
45
46/* Colors */
47uint32_t layer_colors[3] = {
48 [_MAIN] = 0xFF0010,
49 [_ALPHA] = 0x4020FF,
50 [_BETA] = 0x20FF00,
51};
52
53const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
54 /* Main layer
55 │MUTE │ │L_MOD│
56 ┏━━━━━┳━━━━━┯━━━━━┯━━━━━┯━━━━━┯━━━━━┳━━━━━┯━━━━━┯━━━━━┯━━━━━┯━━━━━┳━━━━━┓
57 ┃ TAB ┃ Q │ W │ E │ R │ T ┃ Y │ U │ I │ O │ P ┃ BSP ┃
58 ┣━━━━━╉─────┼─────┼─────┼─────┼─────╂─────┼─────┼─────┼─────┼─────╊━━━━━┫
59 ┃𝛼/ESC┃ A │ S │ D │ F │ G ┃ H │ J │ K │ L │ ; ┃ RET ┃
60 ┣━━━━━╉─────┼─────┼─────┼─────┼─────╂─────┼─────┼─────┼─────┼─────╊━━━━━┫
61 ┃SHIFT┃ Z │ X │ C │ V │ B ┃ N │ M │ , │ . │ / ┃CTL/-┃
62 ┣━━━━━╉─────┼─────┼─────┼─────┼─────╂─────┼─────┼─────┼─────┼─────╊━━━━━┫
63 ┃LCTRL┃ │ │ ALT │ GUI │SPACE┃SPACE│ 𝛽/= │ ' │ │ ┃ \ ┃
64 ┗━━━━━┻━━━━━┷━━━━━┷━━━━━┷━━━━━┷━━━━━┻━━━━━┷━━━━━┷━━━━━┷━━━━━┷━━━━━┻━━━━━┛
65 */
66 [_MAIN] = LAYOUT( \
67 KC_MUTE, LCTL(KC_D),
68 KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC, \
69 KC_ALPHA,KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_ENT, \
70 KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RCTRL,\
71 KC_LCTRL,_______, _______, KC_LALT, KC_LGUI, KC_SPC, KC_SPC, KC_BETA, KC_QUOT, _______, _______, KC_BSLS \
72 ),
73
74 /* Alpha layer (𝛼)
75 │ │ │ │
76 ┏━━━━━┳━━━━━┯━━━━━┯━━━━━┯━━━━━┯━━━━━┳━━━━━┯━━━━━┯━━━━━┯━━━━━┯━━━━━┳━━━━━┓
77 ┃ ┃PREV │PLAY │NEXT │ │NUMLK┃ - │ ^^^ │ ^ │ vvv │ ~ ┃ DEL ┃
78 ┣━━━━━╉─────┼─────┼─────┼─────┼─────╂─────┼─────┼─────┼─────┼─────╊━━━━━┫
79 ┃ ┃ │VOL -│VOL +│ │CPSLK┃HOME │ <-- │ v │ --> │ ` ┃ \ ┃
80 ┣━━━━━╉─────┼─────┼─────┼─────┼─────╂─────┼─────┼─────┼─────┼─────╊━━━━━┫
81 ┃ ┃ │ │ │ │SCRLK┃ END │ = │ [ │ ] │ ( ┃ ) ┃
82 ┣━━━━━╉─────┼─────┼─────┼─────┼─────╂─────┼─────┼─────┼─────┼─────╊━━━━━┫
83 ┃ ┃ │ │ │ │ ┃ │ │ │ │ ┃ ┃
84 ┗━━━━━┻━━━━━┷━━━━━┷━━━━━┷━━━━━┷━━━━━┻━━━━━┷━━━━━┷━━━━━┷━━━━━┷━━━━━┻━━━━━┛
85 */
86 [_ALPHA] = LAYOUT( \
87 _______, _______, \
88 _______, KC_MPRV, KC_MPLY, KC_MNXT, _______, KC_NLCK, KC_MINS, KC_PGUP, KC_UP, KC_PGDN, KC_TILD, KC_DEL, \
89 _______, _______, KC_VOLD, KC_VOLU, _______, KC_CAPS, KC_HOME, KC_LEFT, KC_DOWN, KC_RIGHT,KC_GRV, KC_BSLS, \
90 _______, _______, _______, _______, _______, KC_SLCK, KC_END, KC_EQL, KC_LBRC, KC_RBRC, KC_LPRN ,KC_RPRN, \
91 _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ \
92 ),
93
94 /* Beta layer (𝛽)
95 │ │ │ │
96 ┏━━━━━┳━━━━━┯━━━━━┯━━━━━┯━━━━━┯━━━━━┳━━━━━┯━━━━━┯━━━━━┯━━━━━┯━━━━━┳━━━━━┓
97 ┃ RGB ┃ 1 │ 2 │ 3 │ 4 │ 5 ┃ 6 │ 7 │ 8 │ 9 │ 0 ┃ F12 ┃
98 ┣━━━━━╉─────┼─────┼─────┼─────┼─────╂─────┼─────┼─────┼─────┼─────╊━━━━━┫
99 ┃L_MOD┃ F1 │ F2 │ F3 │ F4 │ F5 ┃ F6 │ F7 │ F8 │ F9 │ F10 ┃ F11 ┃
100 ┣━━━━━╉─────┼─────┼─────┼─────┼─────╂─────┼─────┼─────┼─────┼─────╊━━━━━┫
101 ┃ ┃RESET│DEBUG│ │ │TIME ┃SLEEP│ SEQ │ { │ } │PTSCR┃ ┃
102 ┣━━━━━╉─────┼─────┼─────┼─────┼─────╂─────┼─────┼─────┼─────┼─────╊━━━━━┫
103 ┃ ┃ │ │ │ │ ┃ │ │ │ │ ┃ ┃
104 ┗━━━━━┻━━━━━┷━━━━━┷━━━━━┷━━━━━┷━━━━━┻━━━━━┷━━━━━┷━━━━━┷━━━━━┷━━━━━┻━━━━━┛
105 */
106 [_BETA] = LAYOUT( \
107 _______, _______, \
108 RGB_TOG, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_F12,
109#ifdef LIGHTMODE_ENABLE
110 KC_LIGHT_MODE,
111#else
112 _______,
113#endif
114 KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, \
115 _______, RESET, DEBUG, _______, _______, KC_SET_TIME,KC_SLEP,KC_SEQ,KC_LCBR, KC_RCBR, KC_PSCR, _______, \
116 _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ \
117 )
118};
119
120static bool alpha_pressed = false;
121static bool beta_pressed = false;
122
123static bool ctrl_pressed = false;
124static bool alt_pressed = false;
125static bool shift_pressed = false;
126static bool gui_pressed = false;
127
128static bool is_in_seq = false;
129
130void keyboard_post_init_user(void) {
131 /* debug_enable = true; */
132 /* debug_matrix = true; */
133}
134
135void eeconfig_init_user(void) {
136 set_unicode_input_mode(UC_LNX);
137}
138
139void matrix_init_user(void) {
140#ifdef LIGHTMODE_ENABLE
141 set_light_mode(SMOOTHLED, layer_colors[_MAIN]);
142#endif
143}
144
145static uint32_t last_update = 0;
146static uint8_t hours, minutes, seconds;
147
148void matrix_scan_user(void) {
149 uint32_t now = timer_read32();
150 if (now - last_update > 500) {
151 ds1307_get_time(&hours, &minutes, &seconds);
152 last_update = now;
153 }
154}
155
156static bool is_in_set_time = false;
157static char new_time[6];
158static uint8_t new_time_index = 0;
159
160bool process_record_user(uint16_t keycode, keyrecord_t *record) {
161 if (keycode == KC_SEQ && record->event.pressed) {
162 seq_start();
163 layer_off(_BETA);
164 is_in_seq = true;
165 return false;
166 } else if (is_in_seq) {
167 if (record->event.pressed) {
168 if (!seq_feed(keycode)) {
169 is_in_seq = false;
170 }
171 }
172 return false;
173 }
174 if (keycode == KC_SET_TIME && record->event.pressed) {
175 is_in_set_time = true;
176 new_time_index = 0;
177 } else if (is_in_set_time) {
178 if (!record->event.pressed && keycode >= KC_1 && keycode <= KC_0) {
179 new_time[new_time_index++] = (keycode == KC_0) ? 0 : keycode - KC_1 + 1;
180 if (new_time_index == 6) {
181 is_in_set_time = false;
182 ds1307_set_time(
183 (new_time[0]) * 10 + (new_time[1]),
184 (new_time[2]) * 10 + (new_time[3]),
185 (new_time[4]) * 10 + (new_time[5])
186 );
187 for (int i = 0; i < 6; i++) {
188 tap_code(KC_BSPACE);
189 }
190 }
191 }
192 }
193
194 if (keycode == KC_LCTRL || keycode == KC_RCTRL) {
195 ctrl_pressed = record->event.pressed;
196 } else if (keycode == KC_LALT) {
197 alt_pressed = record->event.pressed;
198 } else if (keycode == KC_LSFT) {
199 shift_pressed = record->event.pressed;
200 } else if (keycode == KC_LGUI) {
201 gui_pressed = record->event.pressed;
202 } else if (keycode == KC_ALPHA) {
203 alpha_pressed = record->event.pressed;
204 } else if (keycode == KC_BETA) {
205 beta_pressed = record->event.pressed;
206 }
207
208 if (keycode == RESET) {
209 rgblight_setrgb(255, 255, 0);
210 }
211#ifdef LIGHTMODE_ENABLE
212 if (record->event.pressed && keycode == KC_LIGHT_MODE) {
213 next_light_mode(layer_colors[_MAIN]);
214 }
215#endif
216 if (keycode == KC_LCTRL) {
217 /* Some Overlay1_Enable fuckery! */
218 (record->event.pressed ? register_code : unregister_code)(KC_LCTRL);
219 return false;
220 }
221 return taphold_process(keycode, record);
222}
223
224layer_state_t layer_state_set_user(layer_state_t state) {
225#ifdef LIGHTMODE_ENABLE
226 uint8_t layer = get_highest_layer(state);
227 update_light_mode(layer_colors[layer]);
228#endif
229 return state;
230}
231
232void encoder_update_user(uint8_t index, bool clockwise) {
233 if (index == 0) {
234 if (!alpha_pressed) {
235 tap_code(clockwise ? KC_VOLD : KC_VOLU);
236 } else {
237 tap_code(clockwise ? KC_MPRV : KC_MNXT);
238 }
239 } else if (index == 1) {
240 if (!alpha_pressed) {
241 tap_code(clockwise ? KC_UP : KC_DOWN);
242 } else {
243 tap_code(clockwise ? KC_PGUP : KC_PGDN);
244 }
245 }
246}
247
248#ifdef OLED_DRIVER_ENABLE
249oled_rotation_t oled_init_user(oled_rotation_t rotation) {
250 return OLED_ROTATION_0;
251}
252
253void oled_task_user(void) {
254 /* Host Keyboard Layer Status */
255 uint8_t current_layer = get_highest_layer(layer_state);
256
257 /* Layer */
258 static const char PROGMEM icons[4][3][6] = {
259 {
260 { 0x80, 0x81, 0x82, 0x83, 0x84, 0 },
261 { 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0 },
262 { 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0 }
263 },
264 {
265 { 0x85, 0x86, 0x87, 0x88, 0x89, 0 },
266 { 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0 },
267 { 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0 }
268 },
269 {
270 { 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0 },
271 { 0xaa, 0xab, 0xac, 0xad, 0xae, 0 },
272 { 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0 }
273 },
274 {
275 { 0x8f, 0x90, 0x91, 0x92, 0x93, 0 },
276 { 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0 },
277 { 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0 }
278 }
279 };
280
281 uint8_t icon_index = current_layer == _MAIN ? 3 : current_layer == _ALPHA ? 1 : 2;
282 for (int i = 0; i < 3; i++) {
283 oled_set_cursor(0, i + 1);
284 oled_write_P(icons[icon_index][i], false);
285 }
286
287 /* Time */
288 oled_set_cursor(6, 0);
289 // oled_write_P(PSTR("-D48 Custom-\n"), false);
290 char buf[16];
291 sprintf(
292 buf,
293 "%02d:%02d:%02d", hours, minutes, seconds
294 );
295 oled_write(buf, false);
296
297 /* Modifiers */
298 static const char PROGMEM mods[][2] = {
299 {0x94, 0x95}, // CTL
300 {0x96, 0x97}, // ALT
301 {0x98, 0x99}, // GUI
302 {0x9a, 0x9b}, // SFT
303 /* {0x9c, 0x9d}, // EMPTY */
304 };
305
306 char mod_data[13] = "\x9c\x9d\x9c\x9d\x9c\x9d\x9c\x9d \x07\x07\x07\0";
307 if (ctrl_pressed) strncpy(mod_data, mods[0], 2);
308 if (alt_pressed) strncpy(mod_data + 2, mods[1], 2);
309 if (gui_pressed) strncpy(mod_data + 4, mods[2], 2);
310 if (shift_pressed) strncpy(mod_data + 6, mods[3], 2);
311 led_t led_usb_state = host_keyboard_led_state();
312 if (led_usb_state.num_lock) mod_data[9] = 'N';
313 if (led_usb_state.caps_lock) mod_data[10] = 'C';
314 if (led_usb_state.scroll_lock) mod_data[11] = 'S';
315
316 oled_set_cursor(6, 1);
317 oled_write(mod_data, false);
318
319 /* Matrix */
320 static const char PROGMEM matrix_chars[] = {
321 0xb4, // None
322 0xb5, // Upper
323 0xb6, // Lower
324 0xb7 // Both
325 };
326
327 for (uint8_t row = 1; row < MATRIX_ROWS; row += 2) {
328 // Skip first row because it's used by the encoders.
329 uint16_t bits1 = matrix_get_row(row);
330 uint16_t bits2 = matrix_get_row(row + 1);
331
332 for (uint8_t col = 0; col < MATRIX_COLS; col++) {
333 uint8_t matrix_char = matrix_chars[((bits1 & (1 << col)) ? 1 : 0) | ((bits2 & (1 << col)) ? 2 : 0)];
334 oled_set_cursor(6 + col, 2 + (row - 1) / 2);
335 oled_write_char(matrix_char, false);
336 }
337 }
338
339}
340#endif
diff --git a/keyboards/handwired/d48/keymaps/anderson/lightmode.c b/keyboards/handwired/d48/keymaps/anderson/lightmode.c
new file mode 100644
index 000000000..bc0595621
--- /dev/null
+++ b/keyboards/handwired/d48/keymaps/anderson/lightmode.c
@@ -0,0 +1,44 @@
1#include "lightmode.h"
2
3#ifdef LIGHTMODE_ENABLE
4
5/* Light modes switcher */
6
7uint8_t light_mode = SMOOTHLED;
8
9void set_light_mode(light_mode_t value, uint32_t color) {
10 light_mode = value;
11 if (light_mode == SMOOTHLED) {
12 smoothled_set(color);
13 } else {
14 dmc12_start(color, true);
15 }
16}
17
18void process_light_mode(void) {
19 if (light_mode == SMOOTHLED) {
20 smoothled_process();
21 } else {
22 dmc12_process();
23 }
24}
25
26void update_light_mode(uint32_t color) {
27 if (light_mode == SMOOTHLED) {
28 smoothled_set(color);
29 } else {
30 dmc12_start(color, false);
31 }
32}
33
34void next_light_mode(uint32_t color) {
35 light_mode = (light_mode + 1) % LIGHT_MODE_SIZE;
36 set_light_mode(light_mode, color);
37}
38
39void matrix_scan_kb(void) {
40 process_light_mode();
41 matrix_scan_user();
42}
43
44#endif
diff --git a/keyboards/handwired/d48/keymaps/anderson/lightmode.h b/keyboards/handwired/d48/keymaps/anderson/lightmode.h
new file mode 100644
index 000000000..0c81e476b
--- /dev/null
+++ b/keyboards/handwired/d48/keymaps/anderson/lightmode.h
@@ -0,0 +1,12 @@
1#include "smoothled.h"
2#include "dmc12.h"
3#include "quantum.h"
4
5/* Light modes */
6enum light_mode_enum { SMOOTHLED, DMC12, LIGHT_MODE_SIZE };
7typedef enum light_mode_enum light_mode_t;
8
9void set_light_mode(light_mode_t value, uint32_t color);
10void process_light_mode(void);
11void update_light_mode(uint32_t color);
12void next_light_mode(uint32_t color);
diff --git a/keyboards/handwired/d48/keymaps/anderson/rules.mk b/keyboards/handwired/d48/keymaps/anderson/rules.mk
new file mode 100644
index 000000000..e925b9a89
--- /dev/null
+++ b/keyboards/handwired/d48/keymaps/anderson/rules.mk
@@ -0,0 +1,2 @@
1OPT_DEFS += -DLIGHTMODE_ENABLE
2SRC += smoothled.c dmc12.c seq.c lightmode.c
diff --git a/keyboards/handwired/d48/keymaps/default/keymap.c b/keyboards/handwired/d48/keymaps/default/keymap.c
new file mode 100644
index 000000000..b7914f3bc
--- /dev/null
+++ b/keyboards/handwired/d48/keymaps/default/keymap.c
@@ -0,0 +1,285 @@
1#include QMK_KEYBOARD_H
2#include <string.h>
3#include <stdio.h>
4#include "taphold.h"
5#include "ds1307.h"
6
7/* Note: don't forget there's some more code in qmk_firmware/users/anderson dir */
8
9#define _MAIN 0
10#define _ALPHA 1
11#define _BETA 2
12
13enum custom_keycodes {
14 KC_MAIN = SAFE_RANGE,
15 KC_ALPHA,
16 KC_BETA,
17 KC_SET_TIME,
18};
19
20/* TapHold is my own implementation of the `LT` macro. It's processed in `process_record_user()`. */
21#define TAPHOLD_CONFIG_SIZE 3
22taphold_t taphold_config[TAPHOLD_CONFIG_SIZE] = {
23 {.key=KC_ALPHA, .mode=TAPHOLD_LAYER, .shortAction=KC_ESC, .longAction=_ALPHA},
24 {.key=KC_BETA, .mode=TAPHOLD_LAYER, .shortAction=KC_EQL, .longAction=_BETA},
25 {.key=KC_RCTRL, .mode=TAPHOLD_MOD, .shortAction=KC_MINS, .longAction=KC_LCTRL},
26};
27uint16_t taphold_config_size = TAPHOLD_CONFIG_SIZE;
28uint32_t taphold_timeout = 90;
29
30/* Colors */
31uint32_t layer_colors[3] = {
32 [_MAIN] = 0xFF0010,
33 [_ALPHA] = 0x4020FF,
34 [_BETA] = 0x20FF00,
35};
36
37const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
38 /* Main layer
39 │MUTE │ │L_MOD│
40 ┏━━━━━┳━━━━━┯━━━━━┯━━━━━┯━━━━━┯━━━━━┳━━━━━┯━━━━━┯━━━━━┯━━━━━┯━━━━━┳━━━━━┓
41 ┃ TAB ┃ Q │ W │ E │ R │ T ┃ Y │ U │ I │ O │ P ┃ BSP ┃
42 ┣━━━━━╉─────┼─────┼─────┼─────┼─────╂─────┼─────┼─────┼─────┼─────╊━━━━━┫
43 ┃𝛼/ESC┃ A │ S │ D │ F │ G ┃ H │ J │ K │ L │ ; ┃ RET ┃
44 ┣━━━━━╉─────┼─────┼─────┼─────┼─────╂─────┼─────┼─────┼─────┼─────╊━━━━━┫
45 ┃SHIFT┃ Z │ X │ C │ V │ B ┃ N │ M │ , │ . │ / ┃CTL/-┃
46 ┣━━━━━╉─────┼─────┼─────┼─────┼─────╂─────┼─────┼─────┼─────┼─────╊━━━━━┫
47 ┃LCTRL┃ │ │ ALT │ GUI │SPACE┃SPACE│ 𝛽/= │ ' │ │ ┃ \ ┃
48 ┗━━━━━┻━━━━━┷━━━━━┷━━━━━┷━━━━━┷━━━━━┻━━━━━┷━━━━━┷━━━━━┷━━━━━┷━━━━━┻━━━━━┛
49 */
50 [_MAIN] = LAYOUT( \
51 KC_MUTE, _______, \
52 KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC, \
53 KC_ALPHA,KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_ENT, \
54 KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RCTRL,\
55 KC_LCTRL,_______, _______, KC_LALT, KC_LGUI, KC_SPC, KC_SPC, KC_BETA, KC_QUOT, _______, _______, KC_BSLS \
56 ),
57
58 /* Alpha layer (𝛼)
59 │ │ │ │
60 ┏━━━━━┳━━━━━┯━━━━━┯━━━━━┯━━━━━┯━━━━━┳━━━━━┯━━━━━┯━━━━━┯━━━━━┯━━━━━┳━━━━━┓
61 ┃ ┃PREV │PLAY │NEXT │ │NUMLK┃ - │ ^^^ │ ^ │ vvv │ ~ ┃ DEL ┃
62 ┣━━━━━╉─────┼─────┼─────┼─────┼─────╂─────┼─────┼─────┼─────┼─────╊━━━━━┫
63 ┃ ┃ │VOL -│VOL +│ │CPSLK┃HOME │ <-- │ v │ --> │ ` ┃ \ ┃
64 ┣━━━━━╉─────┼─────┼─────┼─────┼─────╂─────┼─────┼─────┼─────┼─────╊━━━━━┫
65 ┃ ┃ │ │ │ │SCRLK┃ END │ = │ [ │ ] │ ( ┃ ) ┃
66 ┣━━━━━╉─────┼─────┼─────┼─────┼─────╂─────┼─────┼─────┼─────┼─────╊━━━━━┫
67 ┃ ┃ │ │ │ │ ┃ │ │ │ │ ┃ ┃
68 ┗━━━━━┻━━━━━┷━━━━━┷━━━━━┷━━━━━┷━━━━━┻━━━━━┷━━━━━┷━━━━━┷━━━━━┷━━━━━┻━━━━━┛
69 */
70 [_ALPHA] = LAYOUT( \
71 _______, _______, \
72 _______, KC_MPRV, KC_MPLY, KC_MNXT, _______, KC_NLCK, KC_MINS, KC_PGUP, KC_UP, KC_PGDN, KC_TILD, KC_DEL, \
73 _______, _______, KC_VOLD, KC_VOLU, _______, KC_CAPS, KC_HOME, KC_LEFT, KC_DOWN, KC_RIGHT,KC_GRV, KC_BSLS, \
74 _______, _______, _______, _______, _______, KC_SLCK, KC_END, KC_EQL, KC_LBRC, KC_RBRC, KC_LPRN ,KC_RPRN, \
75 _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ \
76 ),
77
78 /* Beta layer (𝛽)
79 │ │ │ │
80 ┏━━━━━┳━━━━━┯━━━━━┯━━━━━┯━━━━━┯━━━━━┳━━━━━┯━━━━━┯━━━━━┯━━━━━┯━━━━━┳━━━━━┓
81 ┃ RGB ┃ 1 │ 2 │ 3 │ 4 │ 5 ┃ 6 │ 7 │ 8 │ 9 │ 0 ┃ F12 ┃
82 ┣━━━━━╉─────┼─────┼─────┼─────┼─────╂─────┼─────┼─────┼─────┼─────╊━━━━━┫
83 ┃L_MOD┃ F1 │ F2 │ F3 │ F4 │ F5 ┃ F6 │ F7 │ F8 │ F9 │ F10 ┃ F11 ┃
84 ┣━━━━━╉─────┼─────┼─────┼─────┼─────╂─────┼─────┼─────┼─────┼─────╊━━━━━┫
85 ┃ ┃RESET│DEBUG│ │ │TIME ┃SLEEP│ │ { │ } │PTSCR┃ ┃
86 ┣━━━━━╉─────┼─────┼─────┼─────┼─────╂─────┼─────┼─────┼─────┼─────╊━━━━━┫
87 ┃ ┃ │ │ │ │ ┃ │ │ │ │ ┃ ┃
88 ┗━━━━━┻━━━━━┷━━━━━┷━━━━━┷━━━━━┷━━━━━┻━━━━━┷━━━━━┷━━━━━┷━━━━━┷━━━━━┻━━━━━┛
89 */
90 [_BETA] = LAYOUT( \
91 _______, _______, \
92 RGB_TOG, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_F12,
93 _______, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, \
94 _______, RESET, DEBUG, _______, _______, KC_SET_TIME,KC_SLEP,_______,KC_LCBR,KC_RCBR, KC_PSCR, _______, \
95 _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ \
96 )
97};
98
99static bool alpha_pressed = false;
100static bool beta_pressed = false;
101
102static bool ctrl_pressed = false;
103static bool alt_pressed = false;
104static bool shift_pressed = false;
105static bool gui_pressed = false;
106
107void keyboard_post_init_user(void) {
108 /* debug_enable = true; */
109 /* debug_matrix = true; */
110}
111
112void eeconfig_init_user(void) {
113 set_unicode_input_mode(UC_LNX);
114}
115
116static uint32_t last_update = 0;
117static uint8_t hours, minutes, seconds;
118
119void matrix_scan_user(void) {
120 uint32_t now = timer_read32();
121 if (now - last_update > 500) {
122 ds1307_get_time(&hours, &minutes, &seconds);
123 last_update = now;
124 }
125}
126
127static bool is_in_set_time = false;
128static char new_time[6];
129static uint8_t new_time_index = 0;
130
131bool process_record_user(uint16_t keycode, keyrecord_t *record) {
132 if (keycode == KC_SET_TIME && record->event.pressed) {
133 is_in_set_time = true;
134 new_time_index = 0;
135 } else if (is_in_set_time) {
136 if (!record->event.pressed && keycode >= KC_1 && keycode <= KC_0) {
137 new_time[new_time_index++] = (keycode == KC_0) ? 0 : keycode - KC_1 + 1;
138 if (new_time_index == 6) {
139 is_in_set_time = false;
140 ds1307_set_time(
141 (new_time[0]) * 10 + (new_time[1]),
142 (new_time[2]) * 10 + (new_time[3]),
143 (new_time[4]) * 10 + (new_time[5])
144 );
145 for (int i = 0; i < 6; i++) {
146 tap_code(KC_BSPACE);
147 }
148 }
149 }
150 }
151
152 if (keycode == KC_LCTRL || keycode == KC_RCTRL) {
153 ctrl_pressed = record->event.pressed;
154 } else if (keycode == KC_LALT) {
155 alt_pressed = record->event.pressed;
156 } else if (keycode == KC_LSFT) {
157 shift_pressed = record->event.pressed;
158 } else if (keycode == KC_LGUI) {
159 gui_pressed = record->event.pressed;
160 } else if (keycode == KC_ALPHA) {
161 alpha_pressed = record->event.pressed;
162 } else if (keycode == KC_BETA) {
163 beta_pressed = record->event.pressed;
164 }
165
166 if (keycode == RESET) {
167 rgblight_setrgb(255, 255, 0);
168 }
169 if (keycode == KC_LCTRL) {
170 /* Some Overlay1_Enable fuckery! */
171 (record->event.pressed ? register_code : unregister_code)(KC_LCTRL);
172 return false;
173 }
174 return taphold_process(keycode, record);
175}
176
177void encoder_update_user(uint8_t index, bool clockwise) {
178 if (index == 0) {
179 if (!alpha_pressed) {
180 tap_code(clockwise ? KC_VOLD : KC_VOLU);
181 } else {
182 tap_code(clockwise ? KC_MPRV : KC_MNXT);
183 }
184 } else if (index == 1) {
185 if (!alpha_pressed) {
186 tap_code(clockwise ? KC_UP : KC_DOWN);
187 } else {
188 tap_code(clockwise ? KC_PGUP : KC_PGDN);
189 }
190 }
191}
192
193#ifdef OLED_DRIVER_ENABLE
194oled_rotation_t oled_init_user(oled_rotation_t rotation) {
195 return OLED_ROTATION_0;
196}
197
198void oled_task_user(void) {
199 /* Host Keyboard Layer Status */
200 uint8_t current_layer = get_highest_layer(layer_state);
201
202 /* Layer */
203 static const char PROGMEM icons[4][3][6] = {
204 {
205 { 0x80, 0x81, 0x82, 0x83, 0x84, 0 },
206 { 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0 },
207 { 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0 }
208 },
209 {
210 { 0x85, 0x86, 0x87, 0x88, 0x89, 0 },
211 { 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0 },
212 { 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0 }
213 },
214 {
215 { 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0 },
216 { 0xaa, 0xab, 0xac, 0xad, 0xae, 0 },
217 { 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0 }
218 },
219 {
220 { 0x8f, 0x90, 0x91, 0x92, 0x93, 0 },
221 { 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0 },
222 { 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0 }
223 }
224 };
225
226 uint8_t icon_index = current_layer == _MAIN ? 3 : current_layer == _ALPHA ? 1 : 2;
227 for (int i = 0; i < 3; i++) {
228 oled_set_cursor(0, i + 1);
229 oled_write_P(icons[icon_index][i], false);
230 }
231
232 /* Time */
233 oled_set_cursor(6, 0);
234 // oled_write_P(PSTR("-D48 Custom-\n"), false);
235 char buf[16];
236 sprintf(
237 buf,
238 "%02d:%02d:%02d", hours, minutes, seconds
239 );
240 oled_write(buf, false);
241
242 /* Modifiers */
243 static const char PROGMEM mods[][2] = {
244 {0x94, 0x95}, // CTL
245 {0x96, 0x97}, // ALT
246 {0x98, 0x99}, // GUI
247 {0x9a, 0x9b}, // SFT
248 /* {0x9c, 0x9d}, // EMPTY */
249 };
250
251 char mod_data[13] = "\x9c\x9d\x9c\x9d\x9c\x9d\x9c\x9d \x07\x07\x07\0";
252 if (ctrl_pressed) strncpy(mod_data, mods[0], 2);
253 if (alt_pressed) strncpy(mod_data + 2, mods[1], 2);
254 if (gui_pressed) strncpy(mod_data + 4, mods[2], 2);
255 if (shift_pressed) strncpy(mod_data + 6, mods[3], 2);
256 led_t led_usb_state = host_keyboard_led_state();
257 if (led_usb_state.num_lock) mod_data[9] = 'N';
258 if (led_usb_state.caps_lock) mod_data[10] = 'C';
259 if (led_usb_state.scroll_lock) mod_data[11] = 'S';
260
261 oled_set_cursor(6, 1);
262 oled_write(mod_data, false);
263
264 /* Matrix */
265 static const char PROGMEM matrix_chars[] = {
266 0xb4, // None
267 0xb5, // Upper
268 0xb6, // Lower
269 0xb7 // Both
270 };
271
272 for (uint8_t row = 1; row < MATRIX_ROWS; row += 2) {
273 // Skip first row because it's used by the encoders.
274 uint16_t bits1 = matrix_get_row(row);
275 uint16_t bits2 = matrix_get_row(row + 1);
276
277 for (uint8_t col = 0; col < MATRIX_COLS; col++) {
278 uint8_t matrix_char = matrix_chars[((bits1 & (1 << col)) ? 1 : 0) | ((bits2 & (1 << col)) ? 2 : 0)];
279 oled_set_cursor(6 + col, 2 + (row - 1) / 2);
280 oled_write_char(matrix_char, false);
281 }
282 }
283
284}
285#endif
diff --git a/keyboards/handwired/d48/rules.mk b/keyboards/handwired/d48/rules.mk
new file mode 100644
index 000000000..57c83694e
--- /dev/null
+++ b/keyboards/handwired/d48/rules.mk
@@ -0,0 +1,22 @@
1# MCU name
2MCU = STM32F303
3
4# Build Options
5# change yes to no to disable
6#
7BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration
8MOUSEKEY_ENABLE = no # Mouse keys
9EXTRAKEY_ENABLE = yes # Audio control and System control
10CONSOLE_ENABLE = yes # Console for debug
11COMMAND_ENABLE = no # Commands for debug and configuration
12SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
13NKRO_ENABLE = yes # USB Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
14BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
15AUDIO_ENABLE = yes
16USE_I2C = no
17RGBLIGHT_ENABLE = yes
18ENCODER_ENABLE = yes
19OLED_DRIVER_ENABLE = yes
20UNICODE_ENABLE = yes
21
22SRC += ds1307.c taphold.c
diff --git a/keyboards/handwired/d48/taphold.c b/keyboards/handwired/d48/taphold.c
new file mode 100644
index 000000000..0b56a5a6a
--- /dev/null
+++ b/keyboards/handwired/d48/taphold.c
@@ -0,0 +1,29 @@
1#include "taphold.h"
2
3bool taphold_process(uint16_t keycode, keyrecord_t *record) {
4 for (int i = 0; i < taphold_config_size; i++) {
5 taphold_t *config = &taphold_config[i];
6 if (config->key == keycode && record->event.pressed) {
7 if (config->mode == TAPHOLD_LAYER) {
8 layer_on(config->longAction);
9 } else {
10 register_code(config->longAction);
11 }
12 config->time = timer_read32();
13 config->keypos = record->event.key;
14 return false;
15 } else if (KEYEQ(record->event.key, config->keypos) && !record->event.pressed) {
16 if (config->mode == TAPHOLD_LAYER) {
17 layer_off(config->longAction);
18 } else {
19 unregister_code(config->longAction);
20 }
21 if (timer_elapsed32(config->time) < taphold_timeout) {
22 tap_code(config->shortAction);
23 }
24 config->keypos.row = 255;
25 return false;
26 }
27 }
28 return true;
29}
diff --git a/keyboards/handwired/d48/taphold.h b/keyboards/handwired/d48/taphold.h
new file mode 100644
index 000000000..3bc5ca027
--- /dev/null
+++ b/keyboards/handwired/d48/taphold.h
@@ -0,0 +1,25 @@
1#include "quantum.h"
2
3typedef enum taphold_mode_t {
4 TAPHOLD_LAYER,
5 TAPHOLD_MOD
6} taphold_mode_t;
7
8typedef struct taphold_t {
9 uint16_t key;
10 uint32_t time;
11 taphold_mode_t mode;
12 uint16_t shortAction;
13 uint16_t longAction;
14 keypos_t keypos;
15 // We store key pos to properly release the key
16 // even when a different layer is active and the key has a different action now
17} taphold_t;
18
19extern taphold_t taphold_config[];
20extern uint16_t taphold_config_size;
21// Dual keys tap/hold timeout.
22// If key is tapped for less than this value, send key in addition to primary action after completing the action.
23extern uint32_t taphold_timeout;
24
25bool taphold_process(uint16_t keycode, keyrecord_t *record);
diff --git a/users/anderson/dmc12.c b/users/anderson/dmc12.c
new file mode 100644
index 000000000..1dd89dce4
--- /dev/null
+++ b/users/anderson/dmc12.c
@@ -0,0 +1,46 @@
1#include "dmc12.h"
2
3static uint32_t dmc12_color = 0;
4static uint16_t dmc12_timer = 0;
5static int8_t dmc12_current = 0;
6static uint8_t dmc12_direction = 1;
7
8void dmc12_start(uint32_t color, bool reset) {
9 dmc12_color = color;
10 if (reset) {
11 dmc12_timer = 0;
12 dmc12_current = 0;
13 dmc12_direction = 1;
14 }
15}
16
17void dmc12_process(void) {
18 if (!dmc12_timer) {
19 dmc12_timer = timer_read();
20 return;
21 }
22 float dist_from_center = ((float)abs(dmc12_current - RGBLED_NUM / 2)) / ((float)RGBLED_NUM);
23 if (timer_elapsed(dmc12_timer) > dist_from_center * LED_INTERVAL) {
24 dmc12_current += dmc12_direction;
25 if (dmc12_current == 0 || dmc12_current == RGBLED_NUM - 1) {
26 dmc12_direction *= -1;
27 }
28 dmc12_timer = timer_read();
29 for (int i = 0; i < RGBLED_NUM; i++) {
30 if (i > dmc12_current - LED_RADIUS && i < dmc12_current + LED_RADIUS) {
31 float intensity = (LED_RADIUS - abs(i - dmc12_current)) / ((float)LED_RADIUS);
32 if (i != dmc12_current) {
33 intensity /= 4.0;
34 }
35 rgblight_setrgb_at(
36 ((dmc12_color >> 16) & 0xFF) * intensity,
37 ((dmc12_color >> 8) & 0xFF) * intensity,
38 (dmc12_color & 0xFF) * intensity,
39 i
40 );
41 } else {
42 rgblight_setrgb_at(0, 0, 0, i);
43 }
44 }
45 }
46}
diff --git a/users/anderson/dmc12.h b/users/anderson/dmc12.h
new file mode 100644
index 000000000..6b2bf94a5
--- /dev/null
+++ b/users/anderson/dmc12.h
@@ -0,0 +1,9 @@
1// Sexy LED animation.
2
3#include "quantum.h"
4
5#define LED_INTERVAL 160
6#define LED_RADIUS 6
7
8void dmc12_start(uint32_t color, bool reset);
9void dmc12_process(void);
diff --git a/users/anderson/seq.c b/users/anderson/seq.c
new file mode 100644
index 000000000..ff5064859
--- /dev/null
+++ b/users/anderson/seq.c
@@ -0,0 +1,38 @@
1#include "seq.h"
2
3static char buffer[32];
4static uint8_t buffer_size = 0;
5
6void seq_start(void) {
7 buffer_size = 0;
8 SEND_STRING(":");
9}
10
11bool seq_feed(uint16_t keycode) {
12 if (keycode == KC_ENTER) {
13 for (int i = 0; i < buffer_size + 1; i++) {
14 tap_code(KC_BSPACE);
15 }
16 for (int i = 0; i < seq_config_size; i++) {
17 seq_t item = seq_config[i];
18 if (strncmp(item.sequence, buffer, buffer_size) == 0) {
19 send_unicode_string(item.result);
20 }
21 }
22 buffer_size = 0;
23 return false;
24 } else if (keycode == KC_BSPACE) {
25 if (buffer_size) {
26 buffer_size--;
27 tap_code(keycode);
28 }
29 return true;
30 } else {
31 if (keycode >= KC_A && keycode <= KC_Z) {
32 buffer[buffer_size++] = keycode - KC_A + 'a';
33 tap_code(keycode);
34 }
35 return true;
36 }
37}
38
diff --git a/users/anderson/seq.h b/users/anderson/seq.h
new file mode 100644
index 000000000..2da4e7615
--- /dev/null
+++ b/users/anderson/seq.h
@@ -0,0 +1,14 @@
1#include "quantum.h"
2
3#include <string.h>
4
5typedef struct seq_t {
6 const char *sequence;
7 const char *result;
8} seq_t;
9
10extern seq_t seq_config[];
11extern uint16_t seq_config_size;
12
13void seq_start(void);
14bool seq_feed(uint16_t keycode);
diff --git a/users/anderson/smoothled.c b/users/anderson/smoothled.c
new file mode 100644
index 000000000..3af729563
--- /dev/null
+++ b/users/anderson/smoothled.c
@@ -0,0 +1,34 @@
1#include <smoothled.h>
2
3static uint32_t sourceColor = 0x000000;
4static uint32_t currentColor = 0x000000;
5static uint32_t targetColor = 0x000000;
6static int32_t smoothledTimer = -1;
7
8void smoothled_set(uint32_t color) {
9 smoothledTimer = timer_read32();
10 sourceColor = currentColor;
11 targetColor = color;
12}
13
14void smoothled_process(void) {
15 if (smoothledTimer < 0) {
16 return;
17 }
18 int32_t kb = timer_elapsed32(smoothledTimer);
19 int32_t ka = SMOOTH_DURATION - kb;
20 if (kb > SMOOTH_DURATION) {
21 kb = SMOOTH_DURATION;
22 ka = 0;
23 smoothledTimer = -1;
24 }
25 currentColor = 0;
26 for (int i = 2; i >= 0; i--) {
27 uint32_t shift = i * 8;
28 currentColor |= (ka * ((uint32_t)(sourceColor >> shift) & 0xFF) + kb * ((uint32_t)(targetColor >> shift) & 0xFF)) / SMOOTH_DURATION;
29 /*currentColor |= ((targetColor >> shift) & 0xFF);*/
30 currentColor <<= 8;
31 }
32 currentColor >>= 8;
33 rgblight_setrgb((currentColor >> 16) & 0xFF, (currentColor >> 8) & 0xFF, currentColor & 0xFF);
34}
diff --git a/users/anderson/smoothled.h b/users/anderson/smoothled.h
new file mode 100644
index 000000000..bf4f8c177
--- /dev/null
+++ b/users/anderson/smoothled.h
@@ -0,0 +1,6 @@
1#include "quantum.h"
2
3#define SMOOTH_DURATION 160
4
5void smoothled_set(uint32_t color);
6void smoothled_process(void);