]> www.fi.muni.cz Git - bike-lights.git/blob - pattern.c
patterns implemented
[bike-lights.git] / pattern.c
1 #include <avr/io.h>
2
3 #include "lights.h"
4
5 typedef struct {
6         unsigned char mode: 3;
7         unsigned char duration: 5;
8 } pattern_t;
9
10 static unsigned char led_counters[N_LEDS];
11 static pattern_t *led_patterns[N_LEDS];
12
13 #define PATTERN_END { 0, 0 }
14 pattern_t off_pattern[] = {
15         { 0, 5 },
16         PATTERN_END
17 };
18
19 pattern_t blink_pattern[] = {
20         { 1, 0x4 },
21         { 0, 0x8 },
22         PATTERN_END
23 };
24
25 pattern_t pattern_num[] = {
26         { 1, 0x1 },
27         { 0, 0x4 },
28         { 1, 0x1 },
29         { 0, 0x4 },
30         { 1, 0x1 },
31         { 0, 0x4 },
32         { 1, 0x1 },
33         { 0, 0x4 },
34         { 1, 0x1 },
35         { 0, 0x4 },
36         { 1, 0x1 },
37         { 0, 0x4 },
38         { 1, 0x1 },
39         { 0, 0x4 },
40         { 1, 0x1 },
41         { 0, 0x4 },
42         { 1, 0x1 },
43         { 0, 0x1F },
44         PATTERN_END
45 };
46
47 void pattern_init()
48 {
49         unsigned char i;
50
51         for (i = 0; i < N_LEDS; i++) {
52                 led_counters[i] = 0;
53                 led_patterns[i] = off_pattern;
54         }
55 }
56
57 static inline pattern_t *pattern_select(unsigned char n)
58 {
59         log_byte(ambient_zone);
60         return pattern_num + sizeof(pattern_num)/sizeof(pattern_t)
61                 - 1 - 2*(1+ambient_zone);;
62 }
63
64 static void inline led_off(unsigned char n)
65 {
66         if (n == N_PWMLEDS) {
67                 gpio_set(GPIO_LED2, 0);
68         }
69 }
70
71 static void inline led_set_level(unsigned char n, unsigned char level)
72 {
73         if (n == N_PWMLEDS) {
74                 gpio_set(GPIO_LED2, 1);
75         }
76 }
77
78 void patterns_next_tick()
79 {
80         unsigned char i;
81
82         for (i = 0; i < N_LEDS; i++) {
83                 if (led_counters[i] == 0) {
84                         led_patterns[i]++;
85                         if (led_patterns[i]->duration == 0) { // END
86                                 led_patterns[i] = pattern_select(i);
87                         }
88                         led_counters[i] = led_patterns[i]->duration;
89                         if (led_patterns[i]->mode == 0) {
90                                 led_off(i);
91                         } else {
92                                 led_set_level(i, led_patterns[i]->mode - 1);
93                         }
94                 }
95
96                 led_counters[i]--;
97         }
98 }
99