-
Notifications
You must be signed in to change notification settings - Fork 31
/
led-matrix.py
executable file
·154 lines (125 loc) · 3.92 KB
/
led-matrix.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#!/usr/bin/env python3
# Script to generate the mapping of LEDs to the CS and SW registers of the
# IS31FL3741A controller.
#
# The output looks like:
# (0x00, 0), // x:1, y:1, sw:1, cs:1, id:1
# (0x1e, 0), // x:2, y:1, sw:2, cs:1, id:2
# [...]
import math
from dataclasses import dataclass
WIDTH = 9
HEIGHT = 34
@dataclass
class Led:
id: int
x: int
y: int
# Values from 1 to 9
sw: int
# Values from 1 to 34
cs: int
def led_register(self):
# See the IS31FL3741A for how the data pages are separated
if self.cs <= 30 and self.sw >= 7:
page = 1
register = self.cs - 1 + (self.sw-7) * 30
if self.cs <= 30 and self.sw <= 6:
page = 0
register = self.cs - 1 + (self.sw-1) * 30
if self.cs >= 31:
page = 1
register = 0x5A + self.cs - 31 + (self.sw-1) * 9
return (register, page)
def __lt__(self, other):
if self.y == other.y:
return self.x < other.x
else:
return self.y < other.y
def get_leds():
leds = []
# Generate LED mapping as how they are mapped in the Framework Laptop 16 LED Matrix Module
# First down and then right
# CS1 through CS4
for cs in range(1, 5):
for sw in range(1, WIDTH):
leds.append(Led(id=WIDTH * (cs-1) + sw, x=sw, y=cs, sw=sw, cs=cs))
# First right and then down
# CS5 through CS7
base_cs = 4
base_id = WIDTH * base_cs
for cs in range(1, 5):
for sw in range(1, WIDTH):
leds.append(Led(id=base_id + 4 * (sw-1) + cs, x=sw,
y=cs+base_cs, sw=sw, cs=cs+base_cs))
base_id+=5
# First right and then down
# CS9 through CS16
base_cs = 8
base_id = WIDTH * base_cs
for cs in range(1, 9):
for sw in range(1, WIDTH):
leds.append(Led(id=base_id + 8 * (sw-1) + cs, x=sw,
y=cs+base_cs, sw=sw, cs=cs+base_cs))
base_id+=9
# First right and then down
# CS17 through CS32
base_cs = 16
base_id = WIDTH * base_cs
for cs in range(1, 17):
for sw in range(1, WIDTH):
leds.append(Led(id=base_id + 16 * (sw-1) + cs, x=sw,
y=cs+base_cs, sw=sw, cs=cs+base_cs))
base_id+=17
# First down and then right
# CS33 through CS34
base_cs = 32
base_id = WIDTH * base_cs
for cs in range(1, 3):
for sw in range(1, WIDTH):
leds.append(Led(id=base_id + 9 * (cs-1) + sw, x=sw,
y=cs+base_cs, sw=sw, cs=cs+base_cs))
base_id+=3
# DVT2 Last column
five_cycle=[36, 37, 38, 39, 35]
four_cycle=[36, 37, 38, 35]
for y in range(1, HEIGHT+1):
ledid = WIDTH*y
if y >= 5:
ledid = 69 + y%5
if y >= 9:
ledid = 137 + y%9
if y >= 17:
ledid = 273 + y%17
if y >= 33:
ledid = WIDTH*y
if y <= 10:
leds.append(Led(id=ledid, x=WIDTH, y=y, sw=math.ceil(y/5), cs=five_cycle[(y-1)%5]))
else:
sw = 2 + math.ceil((y-10)/4)
cs = four_cycle[(y-10-1)%4]
leds.append(Led(id=ledid, x=WIDTH, y=y, sw=sw, cs=cs))
return leds
def main():
leds = get_leds()
# Needs to be sorted according to x and y
leds.sort()
debug = False
for led in leds:
(register, page) = led.led_register()
if debug:
print(led, "(0x{:02x}, {})".format(register, page))
else:
print("(0x{:02x}, {}), // x:{:2d}, y:{:2d}, sw:{:2d}, cs:{:2d}, id:{:3d}".format(
register, page, led.x, led.y, led.sw, led.cs, led.id))
# print_led(leds, 0, 30)
# For debugging
def get_led(leds, x, y):
return leds[x + y * WIDTH]
# For debugging
def print_led(leds, x, y):
led = get_led(leds, x, y)
(register, page) = led.led_register()
print(led, "(0x{:02x}, {})".format(register, page))
if __name__ == "__main__":
main()