5 static unsigned char pwm_vals[N_PWMLEDS*N_PWMLED_MODES];
6 static unsigned char adc_vals[N_PWMLEDS*N_PWMLED_MODES] = {
8 0x04, 0x14, 0x24, 0x38,
10 0x04, 0x14, 0x24, 0x38,
12 0x04, 0x14, 0x24, 0x38,
15 // TODO: maybe convert this to bitmask to simplify pwmled_needs_adc() ?
16 static unsigned char pwmled_state[N_PWMLEDS];
22 static unsigned char pwmled_mode[N_PWMLEDS];
24 static unsigned char pwm_probes[N_PWMLEDS];
26 static void start_probing(unsigned char n)
28 pwmled_state[n] = ST_PROBING;
38 for (i = 0; i < N_PWMLEDS*N_PWMLED_MODES; i++)
41 for (i = 0; i < N_PWMLEDS; i++) {
46 unsigned char pwmled_needs_adc(unsigned char n)
48 unsigned char st = pwmled_state[n];
49 if (st == ST_PROBING || st == ST_ON)
55 unsigned char pwmled_enabled(unsigned char n)
57 unsigned char st = pwmled_state[n];
58 if (st == ST_OFF || st == ST_ON)
64 void pwmled_set_mode(unsigned char n, unsigned char mode)
66 if (!pwmled_enabled(n))
71 pwmled_state[n] = ST_OFF;
75 if (mode <= N_PWMLED_MODES) {
77 pwm_set(n, pwm_vals[n*N_PWMLED_MODES+mode]);
78 pwmled_state[n] = ST_ON;
79 pwmled_mode[n] = mode;
83 static void inline probing_adc(unsigned char n, uint16_t adcval)
85 unsigned char need_bigger = 0, i;
86 unsigned char *pwm_p = &pwm_vals[n*N_PWMLED_MODES];
87 unsigned char *adc_p = &adc_vals[n*N_PWMLED_MODES];
88 unsigned char pwm = pwm_probes[n];
97 if (pwm == 0 && adcval > 0) { // non-zero voltage with zero PWM?
98 pwmled_state[n] = ST_DISABLED;
106 for (i = 0; i < N_PWMLED_MODES; i++, pwm_p++, adc_p++) {
107 uint16_t adc = *adc_p;
115 if ((n == 1 && pwm > 0x35) || adcval != 0) {
123 if (!need_bigger) { // successfully probed
126 pwmled_state[n] = ST_OFF;
133 if (pwm >= 0x70) { // over the maximum!
135 pwmled_state[n] = ST_DISABLED;
149 static void inline on_adc(unsigned char n, uint16_t adcval)
152 uint16_t new_pwm = led_modes[led_mode].pwmval;
153 uint16_t old_pwm = new_pwm;
154 uint16_t adc_exp = led_modes[led_mode].expected;
156 log_word(((adcval & 0xFF) << 8) | old_pwm);
158 if (2*adcval > 5*adc_exp) { // >2.5x expected, lower significantly
159 new_pwm = 2*old_pwm/3;
160 } else if (3*adcval > 4*adc_exp) { // >1.33x expected, lower a bit
161 new_pwm = old_pwm - 1;
162 } else if (4*adcval < 3*adc_exp) { // 0.75x expected, raise a bit
163 new_pwm = old_pwm + 1;
166 if (new_pwm > 0x60) { // odpojeno?
169 if (new_pwm < 2) { // zkrat?
174 if (new_pwm != old_pwm) {
175 led_modes[led_mode].pwmval = new_pwm;
178 // ADCSRA |= _BV(ADSC);
182 void pwmled_adc(unsigned char n, uint16_t adcval)
184 unsigned char i, probing;
185 switch (pwmled_state[n]) {
187 probing_adc(n, adcval);
190 for (i = 0; i < N_PWMLEDS; i++)
191 if (pwmled_state[i] == ST_PROBING)
195 for (i = 0; i < N_PWMLEDS; i++)
196 log_byte(pwmled_state[i]);
198 for (i = 0; i < N_PWMLEDS*N_PWMLED_MODES; i++)
199 log_byte(pwm_vals[i]);
207 // WTF am I doing in this function then?