From: Jan "Yenya" Kasprzak Date: Fri, 18 Jan 2013 21:50:50 +0000 (+0100) Subject: Merge branch 'master' of ssh://anxur.fi.muni.cz/~kas/html/git/bike-lights X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?p=bike-lights.git;a=commitdiff_plain;h=cb10e19fb7311df4c3c14b64064c3d9a44fdacd1;hp=eb2f91ea7806fd8f5b9a5597fcf5c13855911d71 Merge branch 'master' of ssh://anxur.fi.muni.cz/~kas/html/git/bike-lights Conflicts: firmware/adc.c --- diff --git a/firmware/adc.c b/firmware/adc.c index 5f7849f..9155f32 100644 --- a/firmware/adc.c +++ b/firmware/adc.c @@ -35,7 +35,7 @@ static void inline setup_mux(unsigned char n) break; case 3: // ambient light: 1.1V, ADC5 (PA6), single-ended ADMUX = _BV(REFS1) | _BV(MUX2) | _BV(MUX0); - sum_shift = 0; // 1 measurement + sum_shift = 3; // 3 measurements break; case 4: // batt voltage: 1.1V, ADC6 (PA7), single-ended ADMUX = _BV(REFS1) | _BV(MUX2) | _BV(MUX1); diff --git a/firmware/ambient.c b/firmware/ambient.c index 025b0c4..735f80e 100644 --- a/firmware/ambient.c +++ b/firmware/ambient.c @@ -4,49 +4,64 @@ static uint16_t ambient_val; volatile unsigned char ambient_zone; -static unsigned char ambient_zone_set; -static uint16_t ambient_zones[] = { - 0x0c00, 0x0d00, 0x1000, 0x1800, 0x2800, 0x2f80, 0xffff +/* My photodiode reads 0x00C5 .. 0x033B */ +typedef struct { + uint16_t lo, hi; +} ambient_zone_t; + +/* + * Note: these have to be sorted, starting with 0, ending with 0xFFFF + * and having small overlaps in order to provide a bit of hysteresis. + */ +static ambient_zone_t ambient_zones[] = { + { 0x0000, 0x3400 }, // dark + { 0x3300, 0x5000 }, + { 0x4c00, 0x8000 }, + { 0x7800, 0xffff } }; #define N_AMBIENT_ZONES (sizeof(ambient_zones)/sizeof(ambient_zones[0])) void init_ambient() { ambient_val = 0; - ambient_zone = 0; - ambient_zone_set = 0; + ambient_zone = 1; } void ambient_zone_changed() { +#if 1 log_byte(0xab); log_byte(ambient_zone); log_word(ambient_val); log_flush(); +#endif - pattern_reload(); + // led_set_pattern(N_PWMLEDS, status_led_pattern_select()); + // led_set_pattern(N_PWMLEDS+1, illumination_led_pattern_select()); + // pattern_reload(); } void ambient_adc(uint16_t adcval) { - unsigned char newzone; - - if (!ambient_zone_set) - ambient_val = adcval << 4; - else // running sum - ambient_val += adcval - (ambient_val >> 4); - - newzone = 0; - while (newzone < N_AMBIENT_ZONES-1 - && ambient_zones[newzone] < ambient_val) - newzone++; - - // TODO: implement hysteresis? - if (!ambient_zone_set || newzone != ambient_zone) { - ambient_zone = newzone; - ambient_zone_set = 1; - // ambient_zone_changed(); + unsigned char old_zone = ambient_zone; + + ambient_val += adcval - (ambient_val >> 3); + + while (ambient_zones[ambient_zone].lo > ambient_val) + ambient_zone--; + + while (ambient_zones[ambient_zone].hi < ambient_val) + ambient_zone++; + +#if 0 + if (old_zone != ambient_zone) { + log_byte(0xab); + log_byte(ambient_zone); + log_word(adcval); + log_flush(); } + // ambient_zone_changed(); +#endif } diff --git a/firmware/buttons.c b/firmware/buttons.c index 1263fcb..2e80142 100644 --- a/firmware/buttons.c +++ b/firmware/buttons.c @@ -152,16 +152,16 @@ static void handle_button(unsigned char button, unsigned char cur, } else if (!cur && !prev) { // --- is still pressed --- uint16_t duration = jiffies - button_start[button]; - if (duration > 80) { + if (duration > 160) { set_status_led(button, on1_pattern); // acknowledge long press } } else if (cur && !prev) { // --- just released --- uint16_t duration = jiffies - button_start[button]; - if (duration > 6 && duration < 30) { + if (duration > 6 && duration < 60) { short_press(button); - } else if (duration > 80) { + } else if (duration > 160) { set_status_led(button, NULL); long_press(button); } diff --git a/firmware/control.c b/firmware/control.c index eb35aca..384edc8 100644 --- a/firmware/control.c +++ b/firmware/control.c @@ -30,15 +30,18 @@ static pattern_t panic_pattern[] = { }; pattern_t on1_pattern [] = { - { 1, PATTERN_FOREVER } + { 1, 0x10 }, + PATTERN_END }; static pattern_t on2_pattern [] = { - { 2, PATTERN_FOREVER } + { 2, 0x10 }, + PATTERN_END }; static pattern_t on3_pattern [] = { - { 3, PATTERN_FOREVER } + { 3, 0x10 }, + PATTERN_END }; static pattern_t normal2_pattern[] = { @@ -123,17 +126,13 @@ pattern_t *pwmled0_pattern_select() { // TODO: battery critical -#ifndef TESTING_FW - return normal3_pattern; -#endif - if (towbar_mode) return NULL; switch (ambient_zone) { - case 0: return dim_mode ? NULL : on1_pattern; - case 1: return dim_mode ? NULL : slow2_pattern; - case 2: return dim_mode ? slow3_pattern : slow2_pattern; + case 0: return dim_mode ? NULL : on3_pattern; + case 1: return dim_mode ? NULL : normal3_pattern; + case 2: return dim_mode ? slow3_pattern : normal3_pattern; case 3: default: return dim_mode ? slow3_pattern : normal4_pattern; } @@ -144,8 +143,9 @@ pattern_t *pwmled1_pattern_select() // TODO: battery critical #ifndef TESTING_FW - return off_pattern; + return NULL; #endif + if (towbar_mode) { switch (ambient_zone) { case 0: @@ -204,12 +204,12 @@ pattern_t *illumination_led_pattern_select() ? number_pattern(2, 1) : number_pattern(3, 1); case 2: return dim_mode - ? number_pattern(3, 0) - : number_pattern(4, 0); + ? number_pattern(1, 0) + : number_pattern(2, 0); case 3: default: return dim_mode - ? number_pattern(5, 0) - : number_pattern(6, 0); + ? number_pattern(3, 0) + : number_pattern(4, 0); } } diff --git a/firmware/pattern.c b/firmware/pattern.c index 59692bf..d5720b0 100644 --- a/firmware/pattern.c +++ b/firmware/pattern.c @@ -76,6 +76,11 @@ static pattern_t pattern_invnum[] = { PATTERN_END }; +pattern_t off_pattern[] = { + { 0, 0x1E }, + PATTERN_END +}; + static void led_set_mode(unsigned char n, unsigned char mode) { if (n < N_PWMLEDS) { @@ -87,12 +92,10 @@ static void led_set_mode(unsigned char n, unsigned char mode) void led_set_pattern(unsigned char n, pattern_t *pattern) { - led_patterns[n] = pattern; + if (!pattern) + pattern = off_pattern; - if (!pattern) { - led_set_mode(n, 0); - return; - } + led_patterns[n] = pattern; led_counters[n] = pattern->duration; led_set_mode(n, pattern->mode); diff --git a/firmware/pwmled.c b/firmware/pwmled.c index fcde84a..70cbcf1 100644 --- a/firmware/pwmled.c +++ b/firmware/pwmled.c @@ -5,7 +5,10 @@ typedef struct { uint16_t target, pwm; int16_t err_sum; - unsigned char mode, state, probe_steady; + unsigned char mode, state; + union { + unsigned char probe_steady, mode_changed; + }; uint16_t mode_pwm[N_PWMLED_MODES]; int16_t err_sums[N_PWMLED_MODES]; } pwmled_t; @@ -122,6 +125,7 @@ void pwmled_set_mode(unsigned char n, unsigned char mode) led->state = ST_ON; led->pwm = led->mode_pwm[mode - 1]; led->err_sum = led->err_sums[mode - 1]; + led->mode_changed = 1; pwm_set(n, led->pwm); } else { led->state = ST_OFF; @@ -202,6 +206,10 @@ void pwmled_adc(unsigned char n, uint16_t adcval) if (!ST_IS_ON(led->state)) return; + if (led->state == ST_ON && led->mode_changed) { + led->mode_changed--; + return; + } // FIXME: test for maximum adcval value (adc_max[n]) old_pwm = led->pwm; @@ -218,7 +226,8 @@ void pwmled_adc(unsigned char n, uint16_t adcval) sum -= led->pwm << shift; led->err_sum = sum; - if (led->pwm >= PWM_MAX) { + if (led->pwm >= PWM_MAX + || (n == 1 && led->pwm > PWM_MAX/4 && adcval < 0x08)) { pwmled_err(n); return; }