Skip to content

Commit 45fa66e

Browse files
committed
supports changing hue, saturation and brightness for some backlight modes
1 parent e35fd81 commit 45fa66e

File tree

4 files changed

+138
-24
lines changed

4 files changed

+138
-24
lines changed

keyboard/__init__.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,20 @@ def run(self):
515515
elif kind == ACT_BACKLIGHT:
516516
if action_code == RGB_MOD:
517517
self.backlight.next()
518+
elif action_code == RGB_TOGGLE:
519+
self.backlight.toggle()
520+
elif action_code == RGB_HUE:
521+
self.backlight.hue += 8
522+
elif action_code == HUE_RGB:
523+
self.backlight.hue -= 8
524+
elif action_code == RGB_SAT:
525+
self.backlight.sat += 8
526+
elif action_code == SAT_RGB:
527+
self.backlight.sat -= 8
528+
elif action_code == RGB_VAL:
529+
self.backlight.val += 8
530+
elif action_code == VAL_RGB:
531+
self.backlight.val -= 8
518532
elif kind == ACT_COMMAND:
519533
if action_code == BOOTLOADER:
520534
reset_into_bootloader()

keyboard/model/backlight.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
class Backlight:
22
def __init__(self):
3-
pass
3+
self.hue = 0
4+
self.sat = 255
5+
self.val = 255
46

57
def on(self, r=0xFF, g=0xFF, b=0xFF):
68
pass
@@ -32,3 +34,5 @@ def next(self):
3234
def handle_key(self, key, pressed):
3335
pass
3436

37+
def toggle(self):
38+
pass

keyboard/model/is32fl3733.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,21 +60,38 @@ def setup(self):
6060
self.set_brightness(255)
6161

6262
def set_brightness(self, n):
63+
n &= 0xFF
64+
self._brightness = n
6365
if not self.power.value:
6466
self.power.value = 1
6567

6668
# Global Current Control register (0x01) of page 3
6769
self.page(3)
6870
self.write(1, n)
6971

72+
@property
73+
def brightness(self):
74+
return self._brightness
75+
76+
@brightness.setter
77+
def brightness(self, n):
78+
self.set_brightness(n)
79+
80+
def clear(self):
81+
pixels = self.pixels
82+
for i in range(192):
83+
pixels[i] = 0
84+
7085
def pixel(self, i, r, g, b):
86+
"""Set the pixel. It takes effect after calling update()"""
7187
row = i >> 4 # i // 16
7288
col = i & 15 # i % 16
7389
self.pixels[row * 48 + col] = g
7490
self.pixels[row * 48 + 16 + col] = r
7591
self.pixels[row * 48 + 32 + col] = b
7692

7793
def update_pixel(self, i, r, g, b):
94+
"""Set the pixel and update"""
7895
row = i >> 4 # i // 16
7996
col = i & 15 # i % 16
8097
self.pixels[row * 48 + col] = g

keyboard/model/m60.py

Lines changed: 102 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -73,19 +73,46 @@ def battery_level():
7373
64, 64, 64, 64, 64, 64, 64, 64, 64, 64
7474
))
7575

76+
77+
def hsv_to_rgb(h, s, v):
78+
i = (h * 6) >> 8
79+
f = (h * 6) & 0xFF
80+
81+
p = (v * (256 - s)) >> 8
82+
q = (v * (65536 - s * f)) >> 16
83+
t = (v * (65536 - s * (256 - f))) >> 16
84+
85+
if i == 0: return (v, t, p)
86+
if i == 1: return (q, v, p)
87+
if i == 2: return (p, v, t)
88+
if i == 3: return (p, q, v)
89+
if i == 4: return (t, p, v)
90+
return (v, p, q)
91+
7692

77-
def to_rgb(h, s, v):
93+
def wheel(h):
94+
i = (h * 3) >> 8
95+
a = (h * 3) & 0xFF
96+
b = 255 - a
97+
98+
if i == 0: return (b, a, 0)
99+
if i == 1: return (0, b, a)
100+
101+
return (a, 0, b)
102+
103+
104+
def wheel2(h, v):
78105
i = (h * 3) >> 8
79-
o = (h * 3) & 0xFF
106+
a = (h * 3) & 0xFF
107+
b = 255 - a
80108

81-
f = v * (255 - s) // 255
82-
a = f + ((v - f) * o) >> 8
83-
b = f + ((v - f) * (256 - o)) >> 8
109+
a = a * v // 255
110+
b = b * v // 255
84111

85-
if i == 0: return (b, a, f)
86-
if i == 1: return (f, b, a)
112+
if i == 0: return (b, a, 0)
113+
if i == 1: return (0, b, a)
87114

88-
return (a, f, b)
115+
return (a, 0, b)
89116

90117

91118
class Backlight:
@@ -95,6 +122,7 @@ def __init__(self):
95122
self._bt_led = None
96123
self.pixel = self.dev.pixel
97124

125+
self.enabled = True
98126
self.hsv = [0, 255, 255]
99127
self.keys = {}
100128
self.n = 0
@@ -104,29 +132,73 @@ def __init__(self):
104132
self.mode_function = self.modes[self.mode]
105133
self.dynamic = True
106134

135+
@property
136+
def hue(self):
137+
return self.hsv[0]
138+
139+
@hue.setter
140+
def hue(self, h):
141+
self.hsv[0] = h & 0xFF
142+
if not self.dynamic:
143+
self.mode_function()
144+
145+
@property
146+
def sat(self):
147+
return self.hsv[1]
148+
149+
@sat.setter
150+
def sat(self, s):
151+
self.hsv[1] = 0 if s < 0 else (255 if s > 255 else s)
152+
if not self.dynamic:
153+
self.mode_function()
154+
155+
@property
156+
def val(self):
157+
return self.dev.brightness
158+
159+
@val.setter
160+
def val(self, v):
161+
self.set_brightness(v)
162+
163+
def set_brightness(self, v):
164+
if v <= 0:
165+
self.enabled = False
166+
self.off()
167+
else:
168+
self.enabled = True
169+
self.dev.brightness = v if v < 0xFF else 0xFF
170+
if not self.dynamic:
171+
self.mode_function()
172+
107173
def on(self, r=0xFF, g=0xFF, b=0xFF):
108174
for i in range(63):
109175
self.pixel(i, r, g, b)
110176
self.update()
111177

112178
def off(self):
113-
for i in range(64):
114-
self.pixel(i, 0, 0, 0)
179+
self.dev.clear()
115180
self.update()
116181

182+
def toggle(self):
183+
self.enabled = not self.enabled
184+
if self.enabled:
185+
self.set_mode(self.mode)
186+
else:
187+
self.off()
188+
117189
def mono(self):
118-
self.on(*to_rgb(*self.hsv))
190+
self.on(*hsv_to_rgb(*self.hsv))
119191

120192
def gradient(self):
121193
h0, s0, v0 = self.hsv
122194
for i in range(63):
123195
h = (leds_y[i] + h0) & 0xFF
124-
self.pixel(i, *to_rgb(h, s0, v0))
196+
self.pixel(i, *hsv_to_rgb(h, s0, v0))
125197
self.update()
126198

127199
def spectrum(self, offset=0):
128200
self.n = (self.n + 1) & 0xFF
129-
r, g, b = to_rgb(self.n, 255, 255)
201+
r, g, b = wheel(self.n)
130202
for i in range(63):
131203
self.pixel(i, r, g, b)
132204
self.update()
@@ -136,7 +208,7 @@ def spectrum_x(self):
136208
n = self.n
137209
for i in range(63):
138210
h = (leds_x[i] + n) & 0xFF
139-
self.pixel(i, *to_rgb(h, 255, 255))
211+
self.pixel(i, *wheel(h))
140212
self.update()
141213
self.n = (n + 1) & 0xFF
142214
return True
@@ -145,21 +217,21 @@ def spectrum_y(self):
145217
n = self.n
146218
for i in range(63):
147219
h = (leds_y[i] + n) & 0xFF
148-
self.pixel(i, *to_rgb(h, 255, 255))
220+
self.pixel(i, *wheel(h))
149221
self.update()
150222
self.n = (n + 1) & 0xFF
151223
return True
152224

153225
def handle_key(self, key, pressed):
154-
if self.mode == 6:
226+
if self.enabled and self.mode == 6:
155227
self.keys[key] = 255
156228

157229
def elapse(self):
158230
if 0 == len(self.keys):
159231
return False
160232
for i in self.keys.keys():
161233
t = self.keys[i]
162-
self.pixel(i, *to_rgb(255 - t, 255, t))
234+
self.pixel(i, *wheel2(255 - t, t))
163235
t -= 1
164236
if t < 0:
165237
self.keys.pop(i)
@@ -168,9 +240,6 @@ def elapse(self):
168240
self.update()
169241
return True
170242

171-
def set_brightness(self, v):
172-
self.dev.set_brightness(v)
173-
174243
def set_hid_leds(self, v):
175244
self._hid_leds = v
176245
if self._hid_leds & 2:
@@ -205,13 +274,12 @@ def update(self):
205274
self.dev.power.value = 0
206275

207276
def check(self):
208-
if self.dynamic:
277+
if self.enabled and self.dynamic:
209278
return self.mode_function()
210279
return False
211280

212281
def next(self):
213-
for i in range(63):
214-
self.pixel(i, 0, 0, 0)
282+
self.dev.clear()
215283
self.mode += 1
216284
if self.mode >= len(self.modes):
217285
self.mode = 0
@@ -223,3 +291,14 @@ def next(self):
223291
else:
224292
self.dynamic = False
225293
self.mode_function()
294+
295+
def set_mode(self, mode):
296+
self.mode = mode if mode < len(self.modes) else 0
297+
self.mode_function = self.modes[self.mode]
298+
if self.mode == 6:
299+
self.keys.clear()
300+
if self.mode >= 3:
301+
self.dynamic = True
302+
else:
303+
self.dynamic = False
304+
self.mode_function()

0 commit comments

Comments
 (0)