]> www.fi.muni.cz Git - bike-lights.git/blob - firmware/ambient.c
ambient.c: ambient light zone adjustments
[bike-lights.git] / firmware / ambient.c
1 #include <avr/io.h>
2 #include <avr/eeprom.h>
3
4 #include "lights.h"
5
6 #define AMBIENT_VAL_SHIFT 2
7 static uint16_t ambient_val, ambient_val16;
8 volatile unsigned char ambient_zone;
9 static unsigned char ambient_min, ambient_max, ambient_16drop;
10
11 /* logging */
12 #define AMBIENT_LOG_SIZE 128
13 static unsigned char ambient_log_offset_stored EEMEM;
14 static unsigned char ambient_log_offset;
15 static unsigned char ambient_log[AMBIENT_LOG_SIZE] EEMEM;
16
17 /* My photodiode reads 0x00C5 .. 0x033B */
18 typedef struct {
19         uint16_t lo, hi;
20 } ambient_zone_t;
21
22 /*
23  * Note: these have to be sorted, starting with 0, ending with 0xFFFF
24  * and having small overlaps in order to provide a bit of hysteresis.
25  */
26 static ambient_zone_t ambient_zones[N_AMBIENT_ZONES] = {
27         { 0x0000                   , 0x0250<<AMBIENT_VAL_SHIFT }, // dark
28         { 0x0240<<AMBIENT_VAL_SHIFT, 0x02e0<<AMBIENT_VAL_SHIFT }, // evening
29         { 0x02c0<<AMBIENT_VAL_SHIFT, 0x0306<<AMBIENT_VAL_SHIFT }, // dawn
30         { 0x02f8<<AMBIENT_VAL_SHIFT, 0xffff                    }, // day
31 };
32
33 void init_ambient()
34 {
35         ambient_val = 0;
36         ambient_val16 = 0;
37         ambient_max = 0;
38         ambient_min = 0xFF;
39         ambient_zone = 1;
40         ambient_16drop = 0;
41
42         ambient_log_offset = eeprom_read_byte(&ambient_log_offset_stored);
43
44         if (ambient_log_offset == AMBIENT_LOG_SIZE)
45                 ambient_log_offset = 0; // start over
46 }
47
48 void susp_ambient()
49 {
50         unsigned char stored_offset;
51
52         ambient_log_min_max();
53
54         stored_offset = eeprom_read_byte(&ambient_log_offset_stored);
55         if (stored_offset != ambient_log_offset)
56                 eeprom_write_byte(&ambient_log_offset_stored,
57                         ambient_log_offset);
58 }
59
60 void ambient_log_min_max()
61 {
62         if (ambient_log_offset >= AMBIENT_LOG_SIZE - 1)
63                 return;
64
65         // eeprom_write_byte(&ambient_log[ambient_log_offset++], ambient_min);
66         eeprom_write_byte(&ambient_log[ambient_log_offset++], ambient_max);
67         eeprom_write_byte(&ambient_log[ambient_log_offset++], ambient_16drop);
68
69         ambient_min = 0xFF;
70         ambient_max = 0;
71         ambient_16drop = 0;
72 }
73
74 static inline void ambient_zone_changed()
75 {
76         pwmled_select_brightness();
77         pattern_reload();
78 }
79
80 void ambient_adc(uint16_t adcval)
81 {
82         unsigned char old_zone = ambient_zone;
83         unsigned char byte_val, byte_val16;
84
85         ambient_val += adcval - (ambient_val
86                 >> (AMBIENT_VAL_SHIFT - AMBIENT_ADC_SHIFT));
87
88         while (ambient_zones[ambient_zone].lo > ambient_val)
89                 ambient_zone--;
90
91         while (ambient_zones[ambient_zone].hi < ambient_val)
92                 ambient_zone++;
93
94         byte_val = ambient_val >> (2 + AMBIENT_VAL_SHIFT - AMBIENT_ADC_SHIFT);
95
96         ambient_val16 += byte_val - (ambient_val16 >> 4);
97         byte_val16 = ambient_val16 >> 4;
98
99         if (byte_val16 > byte_val) {
100                 byte_val16 -= byte_val;
101                 if (byte_val16 > ambient_16drop)
102                         ambient_16drop = byte_val16;
103         }
104
105         if (ambient_min > byte_val)
106                 ambient_min = byte_val;
107
108         if (ambient_max < byte_val)
109                 ambient_max = byte_val;
110
111         // user_param ambient zone override
112         if ((byte_val = get_user_param(0)) > 0)
113                 ambient_zone = byte_val - 1;
114
115         if (old_zone != ambient_zone) {
116 #if 0
117                 log_byte(0xab);
118                 log_byte(ambient_zone);
119                 log_word(adcval);
120                 log_flush();
121 #endif
122                 ambient_zone_changed();
123         }
124 }
125