X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?p=bike-lights.git;a=blobdiff_plain;f=firmware%2Fpattern.c;h=e7a8a09314c8a9a57c8c3a29c726c5893afddd01;hp=669225860c4d11583fba63693e653ecc60fe063e;hb=c64b858d2da4d676716d7b4474b67cf04c5ab5e9;hpb=1d5dfb4d273a61877eb5937f93fbd266b782bc7a diff --git a/firmware/pattern.c b/firmware/pattern.c index 6692258..e7a8a09 100644 --- a/firmware/pattern.c +++ b/firmware/pattern.c @@ -85,15 +85,44 @@ pattern_t off_pattern[] = { PATTERN_END }; -static void led_set_mode(unsigned char n, unsigned char mode) +/* + * This is tricky: we use a single pattern for all three pwmleds, + * but on some occasions, we want to be able to modify only a single + * pwmled status without affecting other outputs. For example, during + * braking, we want to modify only the rear pwmled status. We don't + * use a separate "braking" pattern for every other pattern used, but instead + * we change the pwmled0 status regardless of the original value when + * braking. The rule is the following: + * - if during braking the pwmled2 (front) is at mode 2, we switch it to + * mode 3 (which has the same target current) to avoid flicker. + * - if pwmled0 (rear) is off, we set it to mode 2 + * (if it is with mode 1, we keep it at mode 1) + * TODO: something similar should be done for the "entering the dark area" + * condition, where we want to switch pwmled2 (front) on, to mode 2. + */ +void pwmleds_update_mode() { - if (n == 0) { - pwmled_set_mode(0, mode & 3); - pwmled_set_mode(1, (mode >> 2) & 1); - pwmled_set_mode(2, (mode >> 3) & 3); - } else if (n < N_LEDS) { - gpio_set(n - 1, mode); + unsigned char mode, mode0, mode1, mode2; + + mode = led_patterns[0]->mode; + + mode0 = mode & 3; + mode1 = (mode >> 2) & 1; + mode2 = (mode >> 3) & 3; + + if (braking && !battery_critical) { + if (mode0) { + mode0 = 2; + if (mode2 == 2) + mode2 = 3; + } else { + mode0 = 1; + } } + + pwmled_set_mode(0, mode0); + pwmled_set_mode(1, mode1); + pwmled_set_mode(2, mode2); } void led_set_pattern(unsigned char n, pattern_t *pattern) @@ -105,7 +134,11 @@ void led_set_pattern(unsigned char n, pattern_t *pattern) led_counters[n] = fibonacci[pattern->duration_fib]; - led_set_mode(n, pattern->mode); + if (n == 0) { + pwmleds_update_mode(); + } else if (n < N_LEDS) { + gpio_set(n - 1, pattern->mode); + } } void init_pattern()