Skip to content

Commit 147cfc8

Browse files
committed
add some rgb backlight modes
1 parent 6b164d9 commit 147cfc8

File tree

4 files changed

+149
-8
lines changed

4 files changed

+149
-8
lines changed

keyboard/__init__.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -399,10 +399,13 @@ def send_consumer(self, keycode):
399399
print(e)
400400

401401
def get(self):
402-
key = self.matrix.get()
403-
if key & 0x80 == 0:
402+
event = self.matrix.get()
403+
key = event & 0x7F
404+
pressed = event < 0x80
405+
if pressed:
404406
self.heatmap[key] += 1
405-
return key
407+
self.backlight.handle_key(key, pressed)
408+
return event
406409

407410
def run(self):
408411
self.setup()
@@ -413,7 +416,8 @@ def run(self):
413416
ms = matrix.ms
414417
last_time = 0
415418
while True:
416-
n = matrix.wait()
419+
t = 20 if self.backlight.check() else 1000
420+
n = matrix.wait(t)
417421
self.check()
418422
if n == 0:
419423
continue
@@ -508,6 +512,9 @@ def run(self):
508512
self.macro_handler(dev, i, True)
509513
except Exception as e:
510514
print(e)
515+
elif kind == ACT_BACKLIGHT:
516+
if action_code == RGB_MOD:
517+
self.backlight.next()
511518
elif kind == ACT_COMMAND:
512519
if action_code == BOOTLOADER:
513520
reset_into_bootloader()

keyboard/action_code.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,17 @@ def mods_to_keycodes(mods):
546546
ACTION_MOUSEKEY = lambda key: ACTION(ACT_MOUSEKEY, key)
547547

548548
MACRO = lambda n: ACTION(ACT_MACRO, n)
549+
BACKLIGHT = lambda n: ACTION(ACT_BACKLIGHT, n)
550+
551+
RGB_TOGGLE = BACKLIGHT(0)
552+
RGB_MOD = BACKLIGHT(1)
553+
MOD_RGB = BACKLIGHT(2)
554+
RGB_HUE = BACKLIGHT(3)
555+
HUE_RGB = BACKLIGHT(4)
556+
RGB_SAT = BACKLIGHT(5)
557+
SAT_RGB = BACKLIGHT(6)
558+
RGB_VAL = BACKLIGHT(7)
559+
VAL_RGB = BACKLIGHT(8)
549560

550561
COMMAND = lambda opt, n: ACTION(ACT_COMMAND, opt << 8 | n)
551562

keyboard/model/backlight.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,13 @@ def set_bt_led(self, v):
2222

2323
def update(self):
2424
pass
25+
26+
def check(self):
27+
return False
28+
29+
def next(self):
30+
pass
31+
32+
def handle_key(self, key, pressed):
33+
pass
34+

keyboard/model/m60.py

Lines changed: 117 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,15 +57,55 @@ def battery_level():
5757
return BATTERY_VOLTAGE[i]
5858

5959

60+
leds_x = bytearray((
61+
0, 16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 216,
62+
220,200, 184, 168, 152, 136, 120, 104, 88, 72, 56, 40, 24, 4,
63+
6, 27, 43, 59, 75, 91, 107, 123, 139, 155, 171, 187, 214,
64+
210, 180, 164, 148, 132, 116, 100, 84, 68, 52, 36, 10,
65+
2, 22, 42, 102, 162, 182, 202, 222, 123, 82
66+
))
67+
68+
leds_y = bytearray((
69+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
70+
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
71+
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
72+
48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
73+
64, 64, 64, 64, 64, 64, 64, 64, 64, 64
74+
))
75+
76+
77+
def to_rgb(h, s, v):
78+
i = (h * 3) >> 8
79+
o = (h * 3) & 0xFF
80+
81+
f = v * (255 - s) // 255
82+
a = f + ((v - f) * o) >> 8
83+
b = f + ((v - f) * (256 - o)) >> 8
84+
85+
if i == 0: return (b, a, f)
86+
if i == 1: return (f, b, a)
87+
88+
return (a, f, b)
89+
90+
6091
class Backlight:
6192
def __init__(self):
6293
self.dev = IS31FL3733()
6394
self._hid_leds = 0
6495
self._bt_led = None
6596
self.pixel = self.dev.pixel
6697

98+
self.hsv = [0, 255, 255]
99+
self.keys = {}
100+
self.n = 0
101+
102+
self.modes = (self.off, self.mono, self.gradient, self.spectrum, self.spectrum_x, self.spectrum_y, self.elapse)
103+
self.mode = 6
104+
self.mode_function = self.modes[self.mode]
105+
self.dynamic = True
106+
67107
def on(self, r=0xFF, g=0xFF, b=0xFF):
68-
for i in range(64):
108+
for i in range(63):
69109
self.pixel(i, r, g, b)
70110
self.update()
71111

@@ -74,6 +114,60 @@ def off(self):
74114
self.pixel(i, 0, 0, 0)
75115
self.update()
76116

117+
def mono(self):
118+
self.on(*to_rgb(*self.hsv))
119+
120+
def gradient(self):
121+
h0, s0, v0 = self.hsv
122+
for i in range(63):
123+
h = (leds_y[i] + h0) & 0xFF
124+
self.pixel(i, *to_rgb(h, s0, v0))
125+
self.update()
126+
127+
def spectrum(self, offset=0):
128+
self.n = (self.n + 1) & 0xFF
129+
r, g, b = to_rgb(self.n, 255, 255)
130+
for i in range(63):
131+
self.pixel(i, r, g, b)
132+
self.update()
133+
return True
134+
135+
def spectrum_x(self):
136+
n = self.n
137+
for i in range(63):
138+
h = (leds_x[i] + n) & 0xFF
139+
self.pixel(i, *to_rgb(h, 255, 255))
140+
self.update()
141+
self.n = (n + 1) & 0xFF
142+
return True
143+
144+
def spectrum_y(self):
145+
n = self.n
146+
for i in range(63):
147+
h = (leds_y[i] + n) & 0xFF
148+
self.pixel(i, *to_rgb(h, 255, 255))
149+
self.update()
150+
self.n = (n + 1) & 0xFF
151+
return True
152+
153+
def handle_key(self, key, pressed):
154+
if self.mode == 6:
155+
self.keys[key] = 255
156+
157+
def elapse(self):
158+
if 0 == len(self.keys):
159+
return False
160+
for i in self.keys.keys():
161+
t = self.keys[i]
162+
self.pixel(i, *to_rgb(255 - t, 255, t))
163+
t -= 1
164+
if t < 0:
165+
self.keys.pop(i)
166+
else:
167+
self.keys[i] = t
168+
self.update()
169+
return True
170+
77171
def set_brightness(self, v):
78172
self.dev.set_brightness(v)
79173

@@ -84,8 +178,7 @@ def set_hid_leds(self, v):
84178
self.dev.update_pixel(28, 0, 0x80, 0)
85179
else:
86180
self.dev.update_pixel(28, 0, 0, 0)
87-
if self._bt_led is None and not self.dev.any():
88-
self.dev.power.value = 0
181+
self.mode_function()
89182

90183
def set_bt_led(self, v):
91184
if self._bt_led is not None:
@@ -95,7 +188,7 @@ def set_bt_led(self, v):
95188
self._bt_led = v
96189
if v is not None:
97190
self.dev.breathing_pixel(v, 2)
98-
elif (self._hid_leds & 2) == 0:
191+
elif (self._hid_leds & 2) == 0 and not self.dev.any():
99192
self.dev.power.value = 0
100193

101194
def update(self):
@@ -110,3 +203,23 @@ def update(self):
110203
self.dev.update()
111204
if not in_use and not self.dev.any():
112205
self.dev.power.value = 0
206+
207+
def check(self):
208+
if self.dynamic:
209+
return self.mode_function()
210+
return False
211+
212+
def next(self):
213+
for i in range(63):
214+
self.pixel(i, 0, 0, 0)
215+
self.mode += 1
216+
if self.mode >= len(self.modes):
217+
self.mode = 0
218+
self.mode_function = self.modes[self.mode]
219+
if self.mode == 6:
220+
self.keys.clear()
221+
if self.mode >= 3:
222+
self.dynamic = True
223+
else:
224+
self.dynamic = False
225+
self.mode_function()

0 commit comments

Comments
 (0)