X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?p=bike-lights.git;a=blobdiff_plain;f=pwmled.c;h=b4545e7391b205e477d8d882012a566df7823ba4;hp=5c816b3351e4b3077f46084baa6cdb5d3045f6da;hb=1d7ad9daee131c758cdf95b5608f602254f10427;hpb=4db795a97ff9bf1d859b797242df8f4564231f82 diff --git a/pwmled.c b/pwmled.c index 5c816b3..b4545e7 100644 --- a/pwmled.c +++ b/pwmled.c @@ -20,6 +20,7 @@ static unsigned char pwmled_state[N_PWMLEDS]; #define ST_ON 3 static unsigned char pwmled_mode[N_PWMLEDS]; +static unsigned char pwmled_mode_set[N_PWMLEDS]; static unsigned char pwm_probes[N_PWMLEDS]; @@ -35,8 +36,11 @@ void pwmled_init() { unsigned char i; - for (i = 0; i < N_PWMLEDS*N_PWMLED_MODES; i++) + for (i = 0; i < N_PWMLEDS*N_PWMLED_MODES; i++) { pwm_vals[i] = 0; + pwmled_mode[i] = 0; + pwmled_mode_set[i] = 0; + } for (i = 0; i < N_PWMLEDS; i++) { start_probing(i); @@ -66,6 +70,10 @@ void pwmled_set_mode(unsigned char n, unsigned char mode) if (!pwmled_enabled(n)) return; + log_byte(0xF8); + log_byte(n); + log_byte(mode); + if (mode == 0) { pwm_off(n); pwmled_state[n] = ST_OFF; @@ -73,10 +81,15 @@ void pwmled_set_mode(unsigned char n, unsigned char mode) } if (mode <= N_PWMLED_MODES) { + unsigned char pwmval; mode--; - pwm_set(n, pwm_vals[n*N_PWMLED_MODES+mode]); + pwmval = pwm_vals[n*N_PWMLED_MODES+mode]; + pwm_set(n, pwmval); + pwm_on(n); + log_byte(pwmval); pwmled_state[n] = ST_ON; pwmled_mode[n] = mode; + pwmled_mode_set[n] = 1; } } @@ -93,15 +106,16 @@ static void inline probing_adc(unsigned char n, uint16_t adcval) log_word(adcval); #endif -#if 0 - if (pwm == 0 && adcval > 0) { // non-zero voltage with zero PWM? + if (adcval > 0x100 // Too high + || (pwm == 0 && adcval > 0) // non-zero voltage with zero PWM + ) { + pwm_off(n); pwmled_state[n] = ST_DISABLED; - log_byte(n); log_byte(0xF0); + log_byte(n); log_word(adcval); return; } -#endif for (i = 0; i < N_PWMLED_MODES; i++, pwm_p++, adc_p++) { uint16_t adc = *adc_p; @@ -148,13 +162,24 @@ static void inline probing_adc(unsigned char n, uint16_t adcval) // Feedback loop static void inline on_adc(unsigned char n, uint16_t adcval) { -#if 0 - uint16_t new_pwm = led_modes[led_mode].pwmval; - uint16_t old_pwm = new_pwm; - uint16_t adc_exp = led_modes[led_mode].expected; + unsigned char mode = pwmled_mode[n]; + uint16_t adc_exp = adc_vals[n*N_PWMLED_MODES+mode]; + unsigned char *pwm_p = &pwm_vals[n*N_PWMLED_MODES+mode]; + uint16_t old_pwm = *pwm_p; + uint16_t new_pwm = old_pwm; + +#if 1 + log_byte(0xF5); + log_byte(n); + log_word(adcval); +#endif - log_word(((adcval & 0xFF) << 8) | old_pwm); + if (pwmled_mode_set[n]) { // ignore the first reading + pwmled_mode_set[n] = 0; + return; + } + // FIXME: running average? if (2*adcval > 5*adc_exp) { // >2.5x expected, lower significantly new_pwm = 2*old_pwm/3; } else if (3*adcval > 4*adc_exp) { // >1.33x expected, lower a bit @@ -163,20 +188,20 @@ static void inline on_adc(unsigned char n, uint16_t adcval) new_pwm = old_pwm + 1; } - if (new_pwm > 0x60) { // odpojeno? + // FIXME: better disconnect detection + if (new_pwm > 0x60) { // disconnected? new_pwm = 0x60; } - if (new_pwm < 2) { // zkrat? + if (new_pwm < 2) { // short-circuit? new_pwm = 2; } -set_pwm: if (new_pwm != old_pwm) { - led_modes[led_mode].pwmval = new_pwm; - OCR1D = new_pwm; + *pwm_p = new_pwm; + pwm_set(n, new_pwm); + log_byte(0xF9); + log_byte(new_pwm); } - // ADCSRA |= _BV(ADSC); -#endif } void pwmled_adc(unsigned char n, uint16_t adcval) @@ -186,6 +211,7 @@ void pwmled_adc(unsigned char n, uint16_t adcval) case ST_PROBING: probing_adc(n, adcval); +#if 1 probing = 0; for (i = 0; i < N_PWMLEDS; i++) if (pwmled_state[i] == ST_PROBING) @@ -198,12 +224,14 @@ void pwmled_adc(unsigned char n, uint16_t adcval) for (i = 0; i < N_PWMLEDS*N_PWMLED_MODES; i++) log_byte(pwm_vals[i]); log_flush(); + log_set_state(4); } +#endif return; case ST_ON: on_adc(n, adcval); return; - // WTF am I doing in this function then? + // WTF am I doing in this function then? Maybe recently switched off? } }