1
- // placeholder at the moment
1
+ #include " Arduino.h"
2
+ #include " FspTimer.h"
3
+
4
+ #define NUM_LEDS 96
5
+
6
+ static const int pin_zero_index = 28 ;
7
+
8
+ static const uint8_t pins[][2 ] = {
9
+ { 7 , 3 }, // 0
10
+ { 3 , 7 },
11
+ { 7 , 4 },
12
+ { 4 , 7 },
13
+ { 3 , 4 },
14
+ { 4 , 3 },
15
+ { 7 , 8 },
16
+ { 8 , 7 },
17
+ { 3 , 8 },
18
+ { 8 , 3 },
19
+ { 4 , 8 }, // 10
20
+ { 8 , 4 },
21
+ { 7 , 0 },
22
+ { 0 , 7 },
23
+ { 3 , 0 },
24
+ { 0 , 3 },
25
+ { 4 , 0 },
26
+ { 0 , 4 },
27
+ { 8 , 0 },
28
+ { 0 , 8 },
29
+ { 7 , 6 }, // 20
30
+ { 6 , 7 },
31
+ { 3 , 6 },
32
+ { 6 , 3 },
33
+ { 4 , 6 },
34
+ { 6 , 4 },
35
+ { 8 , 6 },
36
+ { 6 , 8 },
37
+ { 0 , 6 },
38
+ { 6 , 0 },
39
+ { 7 , 5 }, // 30
40
+ { 5 , 7 },
41
+ { 3 , 5 },
42
+ { 5 , 3 },
43
+ { 4 , 5 },
44
+ { 5 , 4 },
45
+ { 8 , 5 },
46
+ { 5 , 8 },
47
+ { 0 , 5 },
48
+ { 5 , 0 },
49
+ { 6 , 5 }, // 40
50
+ { 5 , 6 },
51
+ { 7 , 1 },
52
+ { 1 , 7 },
53
+ { 3 , 1 },
54
+ { 1 , 3 },
55
+ { 4 , 1 },
56
+ { 1 , 4 },
57
+ { 8 , 1 },
58
+ { 1 , 8 },
59
+ { 0 , 1 }, // 50
60
+ { 1 , 0 },
61
+ { 6 , 1 },
62
+ { 1 , 6 },
63
+ { 5 , 1 },
64
+ { 1 , 5 },
65
+ { 7 , 2 },
66
+ { 2 , 7 },
67
+ { 3 , 2 },
68
+ { 2 , 3 },
69
+ { 4 , 2 },
70
+ { 2 , 4 },
71
+ { 8 , 2 },
72
+ { 2 , 8 },
73
+ { 0 , 2 },
74
+ { 2 , 0 },
75
+ { 6 , 2 },
76
+ { 2 , 6 },
77
+ { 5 , 2 },
78
+ { 2 , 5 },
79
+ { 1 , 2 },
80
+ { 2 , 1 },
81
+ { 7 , 10 },
82
+ { 10 , 7 },
83
+ { 3 , 10 },
84
+ { 10 , 3 },
85
+ { 4 , 10 },
86
+ { 10 , 4 },
87
+ { 8 , 10 },
88
+ { 10 , 8 },
89
+ { 0 , 10 },
90
+ { 10 , 0 },
91
+ { 6 , 10 },
92
+ { 10 , 6 },
93
+ { 5 , 10 },
94
+ { 10 , 5 },
95
+ { 1 , 10 },
96
+ { 10 , 1 },
97
+ { 2 , 10 },
98
+ { 10 , 2 },
99
+ { 7 , 9 },
100
+ { 9 , 7 },
101
+ { 3 , 9 },
102
+ { 9 , 3 },
103
+ { 4 , 9 },
104
+ { 9 , 4 },
105
+ };
106
+
107
+ #define LED_MATRIX_PORT0_MASK ((1 << 3 ) | (1 << 4 ) | (1 << 11 ) | (1 << 12 ) | (1 << 13 ) | (1 << 15 ))
108
+ #define LED_MATRIX_PORT2_MASK ((1 << 4 ) | (1 << 5 ) | (1 << 6 ) | (1 << 12 ) | (1 << 13 ))
109
+
110
+ static void turnLed (int idx, bool on) {
111
+ R_PORT0->PCNTR1 &= ~((uint32_t ) LED_MATRIX_PORT0_MASK);
112
+ R_PORT2->PCNTR1 &= ~((uint32_t ) LED_MATRIX_PORT2_MASK);
113
+
114
+ if (on) {
115
+ bsp_io_port_pin_t pin_a = g_pin_cfg[pins[idx][0 ] + pin_zero_index].pin ;
116
+ R_PFS->PORT [pin_a >> 8 ].PIN [pin_a & 0xFF ].PmnPFS =
117
+ IOPORT_CFG_PORT_DIRECTION_OUTPUT | IOPORT_CFG_PORT_OUTPUT_HIGH;
118
+
119
+ bsp_io_port_pin_t pin_c = g_pin_cfg[pins[idx][1 ] + pin_zero_index].pin ;
120
+ R_PFS->PORT [pin_c >> 8 ].PIN [pin_c & 0xFF ].PmnPFS =
121
+ IOPORT_CFG_PORT_DIRECTION_OUTPUT | IOPORT_CFG_PORT_OUTPUT_LOW;
122
+ }
123
+ }
124
+
125
+ static uint32_t reverse (uint32_t x)
126
+ {
127
+ x = ((x >> 1 ) & 0x55555555u ) | ((x & 0x55555555u ) << 1 );
128
+ x = ((x >> 2 ) & 0x33333333u ) | ((x & 0x33333333u ) << 2 );
129
+ x = ((x >> 4 ) & 0x0f0f0f0fu ) | ((x & 0x0f0f0f0fu ) << 4 );
130
+ x = ((x >> 8 ) & 0x00ff00ffu ) | ((x & 0x00ff00ffu ) << 8 );
131
+ x = ((x >> 16 ) & 0xffffu ) | ((x & 0xffffu ) << 16 );
132
+ return x;
133
+ }
134
+
135
+ // TODO: this is dangerous, use with care
136
+ #define load (x ) load_wrapper(x, sizeof (x))
137
+
138
+ static uint8_t __attribute__ ((aligned)) framebuffer[NUM_LEDS / 8];
139
+
140
+ class LED_Matrix {
141
+
142
+ public:
143
+ LED_Matrix () {}
144
+ // TODO: find a better name
145
+ // autoscroll will be slower than calling next() at precise times
146
+ void autoscroll (uint32_t interval_ms) {
147
+ _interval = interval_ms;
148
+ }
149
+ void on (size_t pin) {
150
+ turnLed (pin, true );
151
+ }
152
+ void off (size_t pin) {
153
+ turnLed (pin, false );
154
+ }
155
+ void begin () {
156
+ uint8_t type;
157
+ uint8_t ch = FspTimer::get_available_timer (type);
158
+ // TODO: avoid passing "this" argument to remove autoscroll
159
+ led_timer.begin (TIMER_MODE_PERIODIC, type, ch, 10000.0 , 50.0 , turnOnLedISR, this );
160
+ led_timer.setup_overflow_irq ();
161
+ led_timer.open ();
162
+ led_timer.start ();
163
+ }
164
+ void next () {
165
+ uint32_t frame[3 ];
166
+ static int j = 0 ;
167
+ frame[0 ] = reverse (*(_frames+(j*3 )+0 ));
168
+ frame[1 ] = reverse (*(_frames+(j*3 )+1 ));
169
+ frame[2 ] = reverse (*(_frames+(j*3 )+2 ));
170
+ j = (j + 1 ) % _lines;
171
+ memcpy (framebuffer, (uint32_t *)frame, sizeof (frame));
172
+ }
173
+ void load_wrapper (const uint32_t frames[][3 ], uint32_t howMany) {
174
+ _frames = (uint32_t *)frames;
175
+ _lines = (howMany / 3 ) / sizeof (uint32_t );
176
+ }
177
+ private:
178
+ uint32_t * _frames;
179
+ uint32_t _lines;
180
+ uint32_t _interval = 0 ;
181
+ uint32_t _last_interval = 0 ;
182
+ FspTimer led_timer;
183
+
184
+ static void turnOnLedISR (timer_callback_args_t *arg) {
185
+ static volatile int i_isr = 0 ;
186
+ turnLed (i_isr, ((framebuffer[i_isr >> 3 ] & (1 << (i_isr % 8 ))) != 0 ));
187
+ i_isr = (i_isr + 1 ) % NUM_LEDS;
188
+ if (arg != nullptr && arg->p_context != nullptr ) {
189
+ LED_Matrix* _m = (LED_Matrix*)arg->p_context ;
190
+ if (_m->_interval != 0 && millis () - _m->_last_interval > _m->_interval ) {
191
+ _m->next ();
192
+ _m->_last_interval = millis ();
193
+ }
194
+ }
195
+ }
196
+ };
0 commit comments