]> mj.ucw.cz Git - home-hw.git/blob - test-neopixel-square/main.c
fdfe0abdf76666991a0a96895ea6ca919922c892
[home-hw.git] / test-neopixel-square / main.c
1 /*
2  *      Neopixel (WS2812B) Test
3  *
4  *      (c) 2022 Martin Mareš <mj@ucw.cz>
5  */
6
7 #include "util.h"
8
9 #include <libopencm3/cm3/cortex.h>
10 #include <libopencm3/cm3/nvic.h>
11 #include <libopencm3/cm3/systick.h>
12 #include <libopencm3/cm3/scb.h>
13 #include <libopencm3/stm32/dma.h>
14 #include <libopencm3/stm32/gpio.h>
15 #include <libopencm3/stm32/rcc.h>
16 #include <libopencm3/stm32/timer.h>
17 #include <libopencm3/stm32/usart.h>
18
19 #include <string.h>
20
21 /*** Hardware init ***/
22
23 static void clock_init(void)
24 {
25         rcc_clock_setup_pll(&rcc_hse_configs[RCC_CLOCK_HSE8_72MHZ]);
26
27         rcc_periph_clock_enable(RCC_GPIOA);
28         rcc_periph_clock_enable(RCC_GPIOB);
29         rcc_periph_clock_enable(RCC_GPIOC);
30         rcc_periph_clock_enable(RCC_USART1);
31         rcc_periph_clock_enable(RCC_TIM4);
32         rcc_periph_clock_enable(RCC_DMA1);
33
34         rcc_periph_reset_pulse(RST_GPIOA);
35         rcc_periph_reset_pulse(RST_GPIOB);
36         rcc_periph_reset_pulse(RST_GPIOC);
37         rcc_periph_reset_pulse(RST_USART1);
38         rcc_periph_reset_pulse(RST_TIM4);
39 }
40
41 static void gpio_init(void)
42 {
43         // PA9 = TXD1 for debugging console
44         // PA10 = RXD1 for debugging console
45         gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO9);
46         gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, GPIO10);
47
48         // PC13 = BluePill LED
49         gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO13);
50         gpio_clear(GPIOC, GPIO13);
51
52         // PB8 = data for Neopixel
53         gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_OPENDRAIN, GPIO8);
54 }
55
56 static void usart_init(void)
57 {
58         usart_set_baudrate(USART1, 115200);
59         usart_set_databits(USART1, 8);
60         usart_set_stopbits(USART1, USART_STOPBITS_1);
61         usart_set_mode(USART1, USART_MODE_TX);
62         usart_set_parity(USART1, USART_PARITY_NONE);
63         usart_set_flow_control(USART1, USART_FLOWCONTROL_NONE);
64
65         usart_enable(USART1);
66 }
67
68 /*** System ticks ***/
69
70 static volatile u32 ms_ticks;
71
72 void sys_tick_handler(void)
73 {
74         ms_ticks++;
75 }
76
77 static void tick_init(void)
78 {
79         systick_set_frequency(1000, CPU_CLOCK_MHZ * 1000000);
80         systick_counter_enable();
81         systick_interrupt_enable();
82 }
83
84 static void delay_ms(uint ms)
85 {
86         u32 start_ticks = ms_ticks;
87         while (ms_ticks - start_ticks < ms)
88                 ;
89 }
90
91 /*** Neopixels ***/
92
93 #define NPIX_PERIOD 90          // timer runs on 72 MHz, so 90 periods = 1250 ns
94 #define B0 30
95 #define B1 60
96
97 byte neopixel_buf[] = {
98         // 128 cycles low: reset (has to be longer than in the datasheet)
99         0, 0, 0, 0, 0, 0, 0, 0,
100         0, 0, 0, 0, 0, 0, 0, 0,
101         0, 0, 0, 0, 0, 0, 0, 0,
102         0, 0, 0, 0, 0, 0, 0, 0,
103         0, 0, 0, 0, 0, 0, 0, 0,
104         0, 0, 0, 0, 0, 0, 0, 0,
105         0, 0, 0, 0, 0, 0, 0, 0,
106         0, 0, 0, 0, 0, 0, 0, 0,
107         0, 0, 0, 0, 0, 0, 0, 0,
108         0, 0, 0, 0, 0, 0, 0, 0,
109         0, 0, 0, 0, 0, 0, 0, 0,
110         0, 0, 0, 0, 0, 0, 0, 0,
111         0, 0, 0, 0, 0, 0, 0, 0,
112         0, 0, 0, 0, 0, 0, 0, 0,
113         0, 0, 0, 0, 0, 0, 0, 0,
114         0, 0, 0, 0, 0, 0, 0, 0,
115
116         // G7 G6 G5 G4 G3 G2 G1 G0
117         // R7 R6 R5 R4 R3 R2 R1 R0
118         // B7 B6 B5 B4 B3 B2 B1 B0
119
120         B0, B0, B0, B0, B1, B1, B1, B1,
121         B0, B0, B0, B0, B0, B0, B0, B0,
122         B0, B0, B0, B0, B0, B0, B0, B0,
123
124         B0, B0, B0, B0, B0, B0, B0, B0,
125         B0, B0, B0, B0, B0, B0, B0, B0,
126         B0, B0, B0, B0, B1, B1, B1, B1,
127
128         B0, B0, B0, B0, B0, B0, B0, B0,
129         B0, B0, B0, B0, B1, B1, B1, B1,
130         B0, B0, B0, B0, B0, B0, B0, B0,
131
132         B0, B0, B0, B0, B1, B1, B1, B1,
133         B0, B0, B0, B0, B0, B0, B0, B0,
134         B0, B0, B0, B0, B1, B1, B1, B1,
135
136         B0, B0, B0, B0, B1, B1, B1, B1,
137         B0, B0, B0, B0, B1, B1, B1, B1,
138         B0, B0, B0, B0, B0, B0, B0, B0,
139
140         B0, B0, B0, B0, B0, B0, B0, B0,
141         B0, B0, B0, B0, B1, B1, B1, B1,
142         B0, B0, B0, B0, B1, B1, B1, B1,
143
144         B0, B0, B0, B0, B1, B1, B1, B1,
145         B0, B0, B0, B0, B1, B1, B1, B1,
146         B0, B0, B0, B0, B1, B1, B1, B1,
147
148         B0, B0, B0, B0, B0, B0, B0, B0,
149         B0, B0, B0, B0, B0, B0, B0, B0,
150         B0, B0, B0, B0, B1, B1, B1, B1,
151
152         B0, B0, B0, B0, B0, B0, B0, B0,
153         B0, B0, B0, B0, B0, B0, B0, B0,
154         B0, B0, B0, B0, B1, B1, B1, B1,
155
156         B0, B0, B0, B0, B0, B0, B0, B0,
157         B0, B0, B0, B0, B0, B0, B0, B0,
158         B0, B0, B0, B0, B1, B1, B1, B1,
159
160         B0, B0, B0, B0, B0, B0, B0, B0,
161         B0, B0, B0, B0, B0, B0, B0, B0,
162         B0, B0, B0, B0, B1, B1, B1, B1,
163
164         B0, B0, B0, B0, B1, B1, B1, B1,
165         B0, B0, B0, B0, B0, B0, B0, B0,
166         B0, B0, B0, B0, B0, B0, B0, B0,
167
168         B0, B0, B0, B0, B0, B0, B0, B0,
169         B0, B0, B0, B0, B0, B0, B0, B0,
170         B0, B0, B0, B0, B0, B0, B0, B0,
171
172         B0, B0, B0, B0, B0, B0, B0, B0,
173         B0, B0, B0, B0, B0, B0, B0, B0,
174         B0, B0, B0, B0, B0, B0, B0, B0,
175
176         B0, B0, B0, B0, B0, B0, B0, B0,
177         B0, B0, B0, B0, B0, B0, B0, B0,
178         B0, B0, B0, B0, B0, B0, B0, B0,
179
180         B0, B0, B0, B0, B0, B0, B0, B0,
181         B0, B0, B0, B0, B0, B0, B0, B0,
182         B0, B0, B0, B0, B0, B0, B0, B0,
183
184         B0, B0, B0, B0, B0, B0, B0, B0,
185         B0, B0, B0, B0, B0, B0, B0, B0,
186         B0, B0, B0, B0, B0, B0, B0, B0,
187
188         B0, B0, B0, B0, B0, B0, B0, B0,
189         B0, B0, B0, B0, B0, B0, B0, B0,
190         B0, B0, B0, B0, B0, B0, B0, B0,
191
192         B0, B0, B0, B0, B0, B0, B0, B0,
193         B0, B0, B0, B0, B0, B0, B0, B0,
194         B0, B0, B0, B0, B0, B0, B0, B0,
195
196         B0, B0, B0, B0, B0, B0, B0, B0,
197         B0, B0, B0, B0, B0, B0, B0, B0,
198         B0, B0, B0, B0, B0, B0, B0, B0,
199
200         B0, B0, B0, B0, B0, B0, B0, B0,
201         B0, B0, B0, B0, B0, B0, B0, B0,
202         B0, B0, B0, B0, B0, B0, B0, B0,
203
204         B0, B0, B0, B0, B0, B0, B0, B0,
205         B0, B0, B0, B0, B0, B0, B0, B0,
206         B0, B0, B0, B0, B0, B0, B0, B0,
207
208         B0, B0, B0, B0, B0, B0, B0, B0,
209         B0, B0, B0, B0, B0, B0, B0, B0,
210         B0, B0, B0, B0, B0, B0, B0, B0,
211
212         B0, B0, B0, B0, B0, B0, B0, B0,
213         B0, B0, B0, B0, B0, B0, B0, B0,
214         B0, B0, B0, B0, B0, B0, B0, B0,
215
216         B0, B0, B0, B0, B0, B0, B0, B0,
217         B0, B0, B0, B0, B0, B0, B0, B0,
218         B0, B0, B0, B0, B0, B0, B0, B0,
219
220         B0, B0, B0, B0, B0, B0, B0, B0,
221         B0, B0, B0, B0, B0, B0, B0, B0,
222         B0, B0, B0, B0, B0, B0, B0, B0,
223
224         B0, B0, B0, B0, B0, B0, B0, B0,
225         B0, B0, B0, B0, B0, B0, B0, B0,
226         B0, B0, B0, B0, B0, B0, B0, B0,
227
228         B0, B0, B0, B0, B0, B0, B0, B0,
229         B0, B0, B0, B0, B0, B0, B0, B0,
230         B0, B0, B0, B0, B0, B0, B0, B0,
231
232         B0, B0, B0, B0, B0, B0, B0, B0,
233         B0, B0, B0, B0, B0, B0, B0, B0,
234         B0, B0, B0, B0, B0, B0, B0, B0,
235
236         B0, B0, B0, B0, B0, B0, B0, B0,
237         B0, B0, B0, B0, B0, B0, B0, B0,
238         B0, B0, B0, B0, B0, B0, B0, B0,
239
240         B0, B0, B0, B0, B0, B0, B0, B0,
241         B0, B0, B0, B0, B0, B0, B0, B0,
242         B0, B0, B0, B0, B0, B0, B0, B0,
243
244         B0, B0, B0, B0, B0, B0, B0, B0,
245         B0, B0, B0, B0, B0, B0, B0, B0,
246         B0, B0, B0, B0, B0, B0, B0, B0,
247
248         B0, B0, B0, B0, B0, B0, B0, B0,
249         B0, B0, B0, B0, B0, B0, B0, B0,
250         B0, B0, B0, B0, B0, B0, B0, B0,
251
252         B0, B0, B0, B0, B0, B0, B0, B0,
253         B0, B0, B0, B0, B0, B0, B0, B0,
254         B0, B0, B0, B0, B0, B0, B0, B0,
255
256         B0, B0, B0, B0, B0, B0, B0, B0,
257         B0, B0, B0, B0, B0, B0, B0, B0,
258         B0, B0, B0, B0, B0, B0, B0, B0,
259
260         B0, B0, B0, B0, B0, B0, B0, B0,
261         B0, B0, B0, B0, B0, B0, B0, B0,
262         B0, B0, B0, B0, B0, B0, B0, B0,
263
264         B0, B0, B0, B0, B0, B0, B0, B0,
265         B0, B0, B0, B0, B0, B0, B0, B0,
266         B0, B0, B0, B0, B0, B0, B0, B0,
267
268         B0, B0, B0, B0, B0, B0, B0, B0,
269         B0, B0, B0, B0, B0, B0, B0, B0,
270         B0, B0, B0, B0, B0, B0, B0, B0,
271
272         B0, B0, B0, B0, B0, B0, B0, B0,
273         B0, B0, B0, B0, B0, B0, B0, B0,
274         B0, B0, B0, B0, B0, B0, B0, B0,
275
276         B0, B0, B0, B0, B0, B0, B0, B0,
277         B0, B0, B0, B0, B0, B0, B0, B0,
278         B0, B0, B0, B0, B0, B0, B0, B0,
279
280         B0, B0, B0, B0, B0, B0, B0, B0,
281         B0, B0, B0, B0, B0, B0, B0, B0,
282         B0, B0, B0, B0, B0, B0, B0, B0,
283
284         B0, B0, B0, B0, B0, B0, B0, B0,
285         B0, B0, B0, B0, B0, B0, B0, B0,
286         B0, B0, B0, B0, B0, B0, B0, B0,
287
288         B0, B0, B0, B0, B0, B0, B0, B0,
289         B0, B0, B0, B0, B0, B0, B0, B0,
290         B0, B0, B0, B0, B0, B0, B0, B0,
291
292         B0, B0, B0, B0, B0, B0, B0, B0,
293         B0, B0, B0, B0, B0, B0, B0, B0,
294         B0, B0, B0, B0, B0, B0, B0, B0,
295
296         B0, B0, B0, B0, B0, B0, B0, B0,
297         B0, B0, B0, B0, B0, B0, B0, B0,
298         B0, B0, B0, B0, B0, B0, B0, B0,
299
300         B0, B0, B0, B0, B0, B0, B0, B0,
301         B0, B0, B0, B0, B0, B0, B0, B0,
302         B0, B0, B0, B0, B0, B0, B0, B0,
303
304         B0, B0, B0, B0, B0, B0, B0, B0,
305         B0, B0, B0, B0, B0, B0, B0, B0,
306         B0, B0, B0, B0, B0, B0, B0, B0,
307
308         B0, B0, B0, B0, B0, B0, B0, B0,
309         B0, B0, B0, B0, B0, B0, B0, B0,
310         B0, B0, B0, B0, B0, B0, B0, B0,
311
312         B0, B0, B0, B0, B0, B0, B0, B0,
313         B0, B0, B0, B0, B0, B0, B0, B0,
314         B0, B0, B0, B0, B0, B0, B0, B0,
315
316         B0, B0, B0, B0, B0, B0, B0, B0,
317         B0, B0, B0, B0, B0, B0, B0, B0,
318         B0, B0, B0, B0, B0, B0, B0, B0,
319
320         B0, B0, B0, B0, B0, B0, B0, B0,
321         B0, B0, B0, B0, B0, B0, B0, B0,
322         B0, B0, B0, B0, B0, B0, B0, B0,
323
324         B0, B0, B0, B0, B0, B0, B0, B0,
325         B0, B0, B0, B0, B0, B0, B0, B0,
326         B0, B0, B0, B0, B0, B0, B0, B0,
327
328         B0, B0, B0, B0, B0, B0, B0, B0,
329         B0, B0, B0, B0, B0, B0, B0, B0,
330         B0, B0, B0, B0, B0, B0, B0, B0,
331
332         B0, B0, B0, B0, B0, B0, B0, B0,
333         B0, B0, B0, B0, B0, B0, B0, B0,
334         B0, B0, B0, B0, B0, B0, B0, B0,
335
336         B0, B0, B0, B0, B0, B0, B0, B0,
337         B0, B0, B0, B0, B0, B0, B0, B0,
338         B0, B0, B0, B0, B0, B0, B0, B0,
339
340         B0, B0, B0, B0, B0, B0, B0, B0,
341         B0, B0, B0, B0, B0, B0, B0, B0,
342         B0, B0, B0, B0, B0, B0, B0, B0,
343
344         B0, B0, B0, B0, B0, B0, B0, B0,
345         B0, B0, B0, B0, B0, B0, B0, B0,
346         B0, B0, B0, B0, B0, B0, B0, B0,
347
348         B0, B0, B0, B0, B0, B0, B0, B0,
349         B0, B0, B0, B0, B0, B0, B0, B0,
350         B0, B0, B0, B0, B0, B0, B0, B0,
351
352         B0, B0, B0, B0, B0, B0, B0, B0,
353         B0, B0, B0, B0, B0, B0, B0, B0,
354         B0, B0, B0, B0, B0, B0, B0, B0,
355
356         B0, B0, B0, B0, B0, B0, B0, B0,
357         B0, B0, B0, B0, B0, B0, B0, B0,
358         B0, B0, B0, B0, B0, B0, B0, B0,
359
360         B0, B0, B0, B0, B0, B0, B0, B0,
361         B0, B0, B0, B0, B0, B0, B0, B0,
362         B0, B0, B0, B0, B0, B0, B0, B0,
363
364         B0, B0, B0, B0, B0, B0, B0, B0,
365         B0, B0, B0, B0, B0, B0, B0, B0,
366         B0, B0, B0, B0, B0, B0, B0, B0,
367
368         B0, B0, B0, B0, B0, B0, B0, B0,
369         B0, B0, B0, B0, B0, B0, B0, B0,
370         B0, B0, B0, B0, B0, B0, B0, B0,
371
372         B0, B0, B0, B0, B1, B1, B1, B1,
373         B0, B0, B0, B0, B1, B1, B1, B1,
374         B0, B0, B0, B0, B1, B1, B1, B1,
375 };
376
377 static void neopixel_init(void)
378 {
379         // TIM4 update is connected to DMA1 channel 7
380
381         // FIXME: Strange programming sequence as specified in manual
382
383         dma_channel_reset(DMA1, 7);
384
385         dma_set_peripheral_address(DMA1, 7, (u32) &TIM_CCR3(TIM4));
386         dma_set_memory_address(DMA1, 7, (u32) neopixel_buf);
387         dma_set_number_of_data(DMA1, 7, ARRAY_SIZE(neopixel_buf));
388         dma_set_priority(DMA1, 7, DMA_CCR_PL_VERY_HIGH);
389
390         dma_set_read_from_memory(DMA1, 7);
391         dma_enable_circular_mode(DMA1, 7);
392
393         dma_set_memory_size(DMA1, 7, DMA_CCR_MSIZE_8BIT);
394         dma_enable_memory_increment_mode(DMA1, 7);
395
396         dma_set_peripheral_size(DMA1, 7, DMA_CCR_PSIZE_16BIT);
397         dma_disable_peripheral_increment_mode(DMA1, 7);
398
399         dma_enable_channel(DMA1, 7);
400
401         timer_set_prescaler(TIM4, 0);
402         timer_set_mode(TIM4, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
403         timer_disable_preload(TIM4);
404         timer_set_period(TIM4, NPIX_PERIOD - 1);
405
406         timer_set_oc_mode(TIM4, TIM_OC3, TIM_OCM_PWM1);
407         timer_set_oc_value(TIM4, TIM_OC3, 0);
408         timer_set_oc_polarity_high(TIM4, TIM_OC3);
409         timer_enable_oc_output(TIM4, TIM_OC3);
410
411         timer_set_dma_on_update_event(TIM4);
412         TIM_DIER(TIM4) |= TIM_DIER_UDE;
413
414         timer_enable_counter(TIM4);
415 }
416
417 /*** Main ***/
418
419 int main(void)
420 {
421         clock_init();
422         gpio_init();
423         usart_init();
424         tick_init();
425         neopixel_init();
426
427         debug_printf("Hello, world!\n");
428
429 #if 0
430         for (int i=0; i<24*64; i++)
431                 neopixel_buf[128+i] = B1;
432 #endif
433
434         for (;;) {
435                 // wait_for_interrupt();
436                 debug_led(1);
437                 for (int i=4; i<8; i++)
438                         neopixel_buf[128+24*63+i] = B1;
439                 delay_ms(100);
440                 debug_led(0);
441                 for (int i=4; i<8; i++)
442                         neopixel_buf[128+24*63+i] = B0;
443                 delay_ms(500);
444         }
445
446         return 0;
447 }