1+ #include < zephyr/kernel.h>
2+ #include < zephyr/drivers/gpio.h>
3+ #include < zephyr/device.h>
4+ #include < zephyr/drivers/counter.h>
5+ #include < string.h>
6+
7+ static const uint8_t pins[][2 ] = {
8+ { 0 , 1 }, // 0
9+ { 1 , 0 },
10+ { 0 , 2 },
11+ { 2 , 0 },
12+ { 1 , 2 },
13+ { 2 , 1 },
14+ { 0 , 3 },
15+ { 3 , 0 },
16+ { 1 , 3 },
17+ { 3 , 1 },
18+ { 2 , 3 }, // 10
19+ { 3 , 2 },
20+ { 0 , 4 },
21+ { 4 , 0 },
22+ { 1 , 4 },
23+ { 4 , 1 },
24+ { 2 , 4 },
25+ { 4 , 2 },
26+ { 3 , 4 },
27+ { 4 , 3 },
28+ { 0 , 5 }, // 20
29+ { 5 , 0 },
30+ { 1 , 5 },
31+ { 5 , 1 },
32+ { 2 , 5 },
33+ { 5 , 2 },
34+ { 3 , 5 },
35+ { 5 , 3 },
36+ { 4 , 5 },
37+ { 5 , 4 },
38+ { 0 , 6 }, // 30
39+ { 6 , 0 },
40+ { 1 , 6 },
41+ { 6 , 1 },
42+ { 2 , 6 },
43+ { 6 , 2 },
44+ { 3 , 6 },
45+ { 6 , 3 },
46+ { 4 , 6 },
47+ { 6 , 4 },
48+ { 5 , 6 }, // 40
49+ { 6 , 5 },
50+ { 0 , 7 },
51+ { 7 , 0 },
52+ { 1 , 7 },
53+ { 7 , 1 },
54+ { 2 , 7 },
55+ { 7 , 2 },
56+ { 3 , 7 },
57+ { 7 , 3 },
58+ { 4 , 7 }, // 50
59+ { 7 , 4 },
60+ { 5 , 7 },
61+ { 7 , 5 },
62+ { 6 , 7 },
63+ { 7 , 6 },
64+ { 0 , 8 },
65+ { 8 , 0 },
66+ { 1 , 8 },
67+ { 8 , 1 },
68+ { 2 , 8 }, // 60
69+ { 8 , 2 },
70+ { 3 , 8 },
71+ { 8 , 3 },
72+ { 4 , 8 },
73+ { 8 , 4 },
74+ { 5 , 8 },
75+ { 8 , 5 },
76+ { 6 , 8 },
77+ { 8 , 6 },
78+ { 7 , 8 }, // 70
79+ { 8 , 7 },
80+ { 0 , 9 },
81+ { 9 , 0 },
82+ { 1 , 9 },
83+ { 9 , 1 },
84+ { 2 , 9 },
85+ { 9 , 2 },
86+ { 3 , 9 },
87+ { 9 , 3 },
88+ { 4 , 9 }, // 80
89+ { 9 , 4 },
90+ { 5 , 9 },
91+ { 9 , 5 },
92+ { 6 , 9 },
93+ { 9 , 6 },
94+ { 7 , 9 },
95+ { 9 , 7 },
96+ { 8 , 9 },
97+ { 9 , 8 },
98+ { 0 , 10 }, // 90
99+ { 10 , 0 },
100+ { 1 , 10 },
101+ { 10 , 1 },
102+ { 2 , 10 },
103+ { 10 , 2 },
104+ { 3 , 10 },
105+ { 10 , 3 },
106+ { 4 , 10 },
107+ { 10 , 4 },
108+ { 5 , 10 }, // 100
109+ { 10 , 5 },
110+ { 6 , 10 },
111+ { 10 , 6 },
112+ };
113+
114+
115+ const int idxToPin (int idx) {
116+ return idx;
117+ }
118+
119+ #define NUM_MATRIX_LEDS 104
120+ static uint8_t __attribute__ ((aligned)) framebuffer[NUM_MATRIX_LEDS / 8];
121+ static uint8_t __attribute__ ((aligned)) framebuffer_color[NUM_MATRIX_LEDS];
122+
123+ static void turnLed (int idx, bool on) {
124+ GPIOF->MODER &= ~(0xFFFFFF );
125+
126+ if (on) {
127+ GPIOF->BSRR |= (1 << (idxToPin (pins[idx][0 ])) | 1 << (idxToPin (pins[idx][1 ]) + 16 ));
128+ GPIOF->MODER |= (1 << (idxToPin (pins[idx][0 ]) * 2 ) | 1 << (idxToPin (pins[idx][1 ]) * 2 ));
129+ }
130+ }
131+
132+ static uint32_t reverse (uint32_t x)
133+ {
134+ x = ((x >> 1 ) & 0x55555555u ) | ((x & 0x55555555u ) << 1 );
135+ x = ((x >> 2 ) & 0x33333333u ) | ((x & 0x33333333u ) << 2 );
136+ x = ((x >> 4 ) & 0x0f0f0f0fu ) | ((x & 0x0f0f0f0fu ) << 4 );
137+ x = ((x >> 8 ) & 0x00ff00ffu ) | ((x & 0x00ff00ffu ) << 8 );
138+ x = ((x >> 16 ) & 0xffffu ) | ((x & 0xffffu ) << 16 );
139+ return x;
140+ }
141+
142+ static bool color = false ;
143+ static uint8_t _max_grayscale_bits = 3 ;
144+
145+ static void timer_irq_handler_fn (const struct device *counter_dev, void *user_data)
146+ {
147+ static volatile int i_isr = 0 ;
148+ if (color) {
149+ static volatile int counter = 0 ;
150+ switch ((framebuffer_color[i_isr] * 8 / (1 << _max_grayscale_bits))) {
151+ case 0 :
152+ turnLed (i_isr, false );
153+ break ;
154+ case 1 :
155+ turnLed (i_isr, counter % 31 == 0 );
156+ break ;
157+ case 2 :
158+ turnLed (i_isr, counter % 23 == 0 );
159+ break ;
160+ case 3 :
161+ turnLed (i_isr, counter % 15 == 0 );
162+ break ;
163+ case 4 :
164+ turnLed (i_isr, counter % 9 == 0 );
165+ break ;
166+ case 5 :
167+ turnLed (i_isr, counter % 5 == 0 );
168+ break ;
169+ case 6 :
170+ turnLed (i_isr, counter % 3 == 0 );
171+ break ;
172+ case 7 :
173+ turnLed (i_isr, true );
174+ break ;
175+ }
176+ counter++;
177+ } else {
178+ turnLed (i_isr, ((framebuffer[i_isr >> 3 ] & (1 << (i_isr % 8 ))) != 0 ));
179+ }
180+ i_isr = (i_isr + 1 ) % NUM_MATRIX_LEDS;
181+ }
182+
183+ void matrixWrite (uint32_t * buf) {
184+ memcpy (framebuffer, buf, NUM_MATRIX_LEDS/8 );
185+ color = false ;
186+ }
187+
188+ void matrixGrayscaleWrite (uint8_t * buf) {
189+ memcpy (framebuffer_color, buf, NUM_MATRIX_LEDS);
190+ color = true ;
191+ }
192+
193+ void matrixSetGrayscaleBits (uint8_t _max) {
194+ _max_grayscale_bits = _max;
195+ }
196+
197+ #define TIMER DT_NODELABEL (counter_matrix)
198+
199+ void matrixBegin() {
200+ const struct device *const counter_dev = DEVICE_DT_GET (TIMER);
201+ counter_start (counter_dev);
202+
203+ struct counter_top_cfg top_cfg;
204+ top_cfg.ticks = counter_us_to_ticks (counter_dev, 10 );
205+ top_cfg.callback = timer_irq_handler_fn;
206+ top_cfg.user_data = &top_cfg;
207+ top_cfg.flags = 0 ;
208+
209+ int err = counter_set_top_value (counter_dev, &top_cfg);
210+ if (err) {
211+ printk (" Failed to set counter_set_top_value" );
212+ }
213+
214+ // uint32_t buf[4] = {0x38E22, 0x8A09375D, 0x824A288E, 0x38000000};
215+ /*
216+ uint32_t buf[4] = {
217+ 0b00000000000000011100011100010001,
218+ 0b01000101000001001001101110101110,
219+ 0b11000001001001010001010001000111,
220+ 0b00011100000000000000000000000000};
221+ */
222+ uint32_t buf[4 ] = {
223+ 0b01111111000000100000100000010000 ,
224+ 0b01000000100000100000010001010000 ,
225+ 0b00100001100000011111111000000000 ,
226+ 0b00110000000000000000000000000000 };
227+ for (int i = 0 ; i < 4 ; i++) {
228+ buf[i] = reverse (buf[i]);
229+ }
230+ // matrixWrite(buf);
231+ }
0 commit comments