diff options
Diffstat (limited to 'quantum/led.c')
-rw-r--r-- | quantum/led.c | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/quantum/led.c b/quantum/led.c new file mode 100644 index 000000000..3e30b1a5a --- /dev/null +++ b/quantum/led.c | |||
@@ -0,0 +1,137 @@ | |||
1 | /* Copyright 2020 zvecr<git@zvecr.com> | ||
2 | * | ||
3 | * This program is free software: you can redistribute it and/or modify | ||
4 | * it under the terms of the GNU General Public License as published by | ||
5 | * the Free Software Foundation, either version 2 of the License, or | ||
6 | * (at your option) any later version. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
15 | */ | ||
16 | #include "quantum.h" | ||
17 | |||
18 | #ifdef BACKLIGHT_ENABLE | ||
19 | # include "backlight.h" | ||
20 | extern backlight_config_t backlight_config; | ||
21 | #else | ||
22 | // Cannot use BACKLIGHT_CAPS_LOCK without backlight being enabled | ||
23 | # undef BACKLIGHT_CAPS_LOCK | ||
24 | #endif | ||
25 | |||
26 | #ifndef LED_PIN_ON_STATE | ||
27 | # define LED_PIN_ON_STATE 1 | ||
28 | #endif | ||
29 | |||
30 | #if defined(BACKLIGHT_CAPS_LOCK) | ||
31 | /** \brief Caps Lock indicator using backlight (for keyboards without dedicated LED) | ||
32 | */ | ||
33 | static void handle_backlight_caps_lock(led_t led_state) { | ||
34 | // Use backlight as Caps Lock indicator | ||
35 | uint8_t bl_toggle_lvl = 0; | ||
36 | |||
37 | if (led_state.caps_lock && !backlight_config.enable) { | ||
38 | // Turning Caps Lock ON and backlight is disabled in config | ||
39 | // Toggling backlight to the brightest level | ||
40 | bl_toggle_lvl = BACKLIGHT_LEVELS; | ||
41 | } else if (!led_state.caps_lock && backlight_config.enable) { | ||
42 | // Turning Caps Lock OFF and backlight is enabled in config | ||
43 | // Toggling backlight and restoring config level | ||
44 | bl_toggle_lvl = backlight_config.level; | ||
45 | } | ||
46 | |||
47 | // Set level without modify backlight_config to keep ability to restore state | ||
48 | backlight_set(bl_toggle_lvl); | ||
49 | } | ||
50 | #endif | ||
51 | |||
52 | /** \brief Lock LED set callback - keymap/user level | ||
53 | * | ||
54 | * \deprecated Use led_update_user() instead. | ||
55 | */ | ||
56 | __attribute__((weak)) void led_set_user(uint8_t usb_led) {} | ||
57 | |||
58 | /** \brief Lock LED set callback - keyboard level | ||
59 | * | ||
60 | * \deprecated Use led_update_kb() instead. | ||
61 | */ | ||
62 | __attribute__((weak)) void led_set_kb(uint8_t usb_led) { led_set_user(usb_led); } | ||
63 | |||
64 | /** \brief Lock LED update callback - keymap/user level | ||
65 | * | ||
66 | * \return True if led_update_kb() should run its own code, false otherwise. | ||
67 | */ | ||
68 | __attribute__((weak)) bool led_update_user(led_t led_state) { return true; } | ||
69 | |||
70 | /** \brief Lock LED update callback - keyboard level | ||
71 | * | ||
72 | * \return Ignored for now. | ||
73 | */ | ||
74 | __attribute__((weak)) bool led_update_kb(led_t led_state) { | ||
75 | bool res = led_update_user(led_state); | ||
76 | if (res) { | ||
77 | #if defined(LED_NUM_LOCK_PIN) || defined(LED_CAPS_LOCK_PIN) || defined(LED_SCROLL_LOCK_PIN) || defined(LED_COMPOSE_PIN) || defined(LED_KANA_PIN) | ||
78 | # if LED_PIN_ON_STATE == 0 | ||
79 | // invert the whole thing to avoid having to conditionally !led_state.x later | ||
80 | led_state.raw = ~led_state.raw; | ||
81 | # endif | ||
82 | |||
83 | # ifdef LED_NUM_LOCK_PIN | ||
84 | writePin(LED_NUM_LOCK_PIN, led_state.num_lock); | ||
85 | # endif | ||
86 | # ifdef LED_CAPS_LOCK_PIN | ||
87 | writePin(LED_CAPS_LOCK_PIN, led_state.caps_lock); | ||
88 | # endif | ||
89 | # ifdef LED_SCROLL_LOCK_PIN | ||
90 | writePin(LED_SCROLL_LOCK_PIN, led_state.scroll_lock); | ||
91 | # endif | ||
92 | # ifdef LED_COMPOSE_PIN | ||
93 | writePin(LED_COMPOSE_PIN, led_state.compose); | ||
94 | # endif | ||
95 | # ifdef LED_KANA_PIN | ||
96 | writePin(LED_KANA_PIN, led_state.kana); | ||
97 | # endif | ||
98 | #endif | ||
99 | } | ||
100 | return res; | ||
101 | } | ||
102 | |||
103 | /** \brief Initialise any LED related hardware and/or state | ||
104 | */ | ||
105 | __attribute__((weak)) void led_init_ports(void) { | ||
106 | #ifdef LED_NUM_LOCK_PIN | ||
107 | setPinOutput(LED_NUM_LOCK_PIN); | ||
108 | writePin(LED_NUM_LOCK_PIN, !LED_PIN_ON_STATE); | ||
109 | #endif | ||
110 | #ifdef LED_CAPS_LOCK_PIN | ||
111 | setPinOutput(LED_CAPS_LOCK_PIN); | ||
112 | writePin(LED_CAPS_LOCK_PIN, !LED_PIN_ON_STATE); | ||
113 | #endif | ||
114 | #ifdef LED_SCROLL_LOCK_PIN | ||
115 | setPinOutput(LED_SCROLL_LOCK_PIN); | ||
116 | writePin(LED_SCROLL_LOCK_PIN, !LED_PIN_ON_STATE); | ||
117 | #endif | ||
118 | #ifdef LED_COMPOSE_PIN | ||
119 | setPinOutput(LED_COMPOSE_PIN); | ||
120 | writePin(LED_COMPOSE_PIN, !LED_PIN_ON_STATE); | ||
121 | #endif | ||
122 | #ifdef LED_KANA_PIN | ||
123 | setPinOutput(LED_KANA_PIN); | ||
124 | writePin(LED_KANA_PIN, !LED_PIN_ON_STATE); | ||
125 | #endif | ||
126 | } | ||
127 | |||
128 | /** \brief Entrypoint for protocol to LED binding | ||
129 | */ | ||
130 | __attribute__((weak)) void led_set(uint8_t usb_led) { | ||
131 | #ifdef BACKLIGHT_CAPS_LOCK | ||
132 | handle_backlight_caps_lock((led_t)usb_led); | ||
133 | #endif | ||
134 | |||
135 | led_set_kb(usb_led); | ||
136 | led_update_kb((led_t)usb_led); | ||
137 | } \ No newline at end of file | ||