From: Jan "Yenya" Kasprzak Date: Sat, 11 May 2013 22:56:05 +0000 (+0200) Subject: binary patterns X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?p=tinyboard.git;a=commitdiff_plain;h=d09c1dcb07782f32226fc5ab591dc2a40e8bb3fe binary patterns We use on/off for patterns, so I have rewritten the pattern handling, removing the pattern_t type altogether, and changed it to use binary strings of data instead. This uses less RAM for pattern definitions. I have also changed blink_pattern to include morse code text (generated by morse.pl), with kids' names. --- diff --git a/projects/step-up/control.c b/projects/step-up/control.c index bdfe53d..4ffb71c 100644 --- a/projects/step-up/control.c +++ b/projects/step-up/control.c @@ -3,25 +3,62 @@ #include "lights.h" -static pattern_t on_pattern [] = { - { 1, 0x10 }, - PATTERN_END +static unsigned char on_pattern[] = { + /* 8 bits */ + 0b11111111, }; -static pattern_t blink_pattern[] = { - { 1, 0x1 }, - { 0, 0x2 }, - { 1, 0x1 }, - { 0, 0x8 }, - { 1, 0x1 }, - { 0, 0x8 }, - PATTERN_END +#define IVA + +static unsigned char blink_pattern[] = { +#ifdef IVA + /* ../...-/..-/.../-.-/.-// */ + /* 137 bits, 19.7% on */ + 0b10000100, + 0b00000000, + 0b10000100, + 0b00100001, + 0b11000000, + 0b00001000, + 0b01000011, + 0b10000000, + 0b00010000, + 0b10000100, + 0b00000000, + 0b11100001, + 0b00001110, + 0b00000000, + 0b01000011, + 0b10000000, + 0b00000000, + 0b00000000, +#else /* FILIP */ + /* ..-./../.-../../.--.// */ + /* 124 bits, 19.4% on */ + 0b10000100, + 0b00111000, + 0b01000000, + 0b00001000, + 0b01000000, + 0b00001000, + 0b01110000, + 0b10000100, + 0b00000000, + 0b10000100, + 0b00000000, + 0b10000111, + 0b00001110, + 0b00010000, + 0b00000000, + 0b00000000, +#endif }; -static pattern_t slow_pattern[] = { - { 1, 0x1 }, - { 0, 0x18 }, - PATTERN_END +static unsigned char slow_pattern[] = { + /* 24 bits */ + 0b00010000, + 0b00000000, + 0b00000000, }; static unsigned char light_mode; @@ -80,35 +117,36 @@ void long_press() power_down(); } -pattern_t *pwmled_pattern_select() +void pwmled_pattern_select(unsigned char led) { - if (e.shutdown_in_progress) - return NULL; - - if (e.battery_low) - return slow_pattern; - - if (light_mode == 0) { - return slow_pattern; + if (e.shutdown_in_progress) { + led_set_pattern(led, 0, 0, NULL); + } else if (e.battery_low) { + led_set_pattern(led, 24, 0, slow_pattern); + } else if (light_mode == 0) { + led_set_pattern(led, 24, 0, slow_pattern); } else if (light_mode < N_PWMLED_MODES) { - return blink_pattern; +#ifdef IVA + led_set_pattern(led, 137, 0, blink_pattern); +#else /* FILIP */ + led_set_pattern(led, 124, 0, blink_pattern); +#endif } else { - return on_pattern; + led_set_pattern(led, 8, 0, on_pattern); } } -pattern_t *status_led_pattern_select() +void status_led_pattern_select(unsigned char led) { - if (e.shutdown_in_progress) - return on_pattern; - - if (e.pwmled_error) - return number_pattern(3, 1); - - if (e.battery_low) - return number_pattern(1, 1); - - return number_pattern(battery_gauge(), 0); + if (e.shutdown_in_progress) { + led_set_pattern(led, 8, 0, on_pattern); + } else if (e.pwmled_error) { + led_set_number_pattern(led, 1, 1); + } else if (e.battery_low) { + led_set_number_pattern(led, 1, 1); + } else { + led_set_number_pattern(led, battery_gauge(), 0); + } } #if 0 diff --git a/projects/step-up/lights.h b/projects/step-up/lights.h index c4f5666..e3bd6e3 100644 --- a/projects/step-up/lights.h +++ b/projects/step-up/lights.h @@ -42,16 +42,12 @@ void pwmled_set_target(unsigned char mode); void pwmled_on_off(unsigned char on); /* pattern.c */ -typedef struct { - unsigned char mode: 3; - unsigned char duration: 5; -} pattern_t; - -#define PATTERN_END { 0, 0 } void init_pattern(); void patterns_next_tick(); -void led_set_pattern(unsigned char led, pattern_t *pattern); -pattern_t *number_pattern(unsigned char num, unsigned char inv); +void led_set_pattern(unsigned char led, unsigned char bits_len, + unsigned char bits_start, unsigned char *data); +void led_set_number_pattern(unsigned char led, + unsigned char num, unsigned char inv); void pattern_reload(); /* buttons.c */ @@ -73,8 +69,8 @@ void long_press(); void short_press(); void brake_on(); void brake_off(); -pattern_t *pwmled_pattern_select(); -pattern_t *status_led_pattern_select(); +void pwmled_pattern_select(unsigned char led); +void status_led_pattern_select(unsigned char led); #define ERR_BATTERY 1 #define ERR_PWMLED 2 void set_error(unsigned char err); diff --git a/projects/step-up/pattern.c b/projects/step-up/pattern.c index 3336b58..44c6d1a 100644 --- a/projects/step-up/pattern.c +++ b/projects/step-up/pattern.c @@ -4,161 +4,125 @@ #include "lights.h" #define N_LEDS 2 -static unsigned char led_counters[N_LEDS]; -static pattern_t *led_patterns[N_LEDS]; - -static pattern_t pattern_num[] = { - { 0, 0x5 }, - { 1, 0x1 }, /* 10 */ - { 0, 0x5 }, - { 1, 0x1 }, /* 9 */ - { 0, 0x5 }, - { 1, 0x1 }, /* 8 */ - { 0, 0x5 }, - { 1, 0x1 }, /* 7 */ - { 0, 0x5 }, - { 1, 0x1 }, /* 6 */ - { 0, 0x5 }, - { 1, 0x1 }, /* 5 */ - { 0, 0x5 }, - { 1, 0x1 }, /* 4 */ - { 0, 0x5 }, - { 1, 0x1 }, /* 3 */ - { 0, 0x5 }, - { 1, 0x1 }, /* 2 */ - { 0, 0x5 }, - { 1, 0x1 }, /* 1 */ - { 0, 0xF }, - PATTERN_END -}; - -static pattern_t pattern_invnum[] = { - { 1, 0x5 }, - { 0, 0x1 }, /* 10 */ - { 1, 0x5 }, - { 0, 0x1 }, /* 9 */ - { 1, 0x5 }, - { 0, 0x1 }, /* 8 */ - { 1, 0x5 }, - { 0, 0x1 }, /* 7 */ - { 1, 0x5 }, - { 0, 0x1 }, /* 6 */ - { 1, 0x5 }, - { 0, 0x1 }, /* 5 */ - { 1, 0x5 }, - { 0, 0x1 }, /* 4 */ - { 1, 0x5 }, - { 0, 0x1 }, /* 3 */ - { 1, 0x5 }, - { 0, 0x1 }, /* 2 */ - { 1, 0x5 }, - { 0, 0x1 }, /* 1 */ - { 1, 0xF }, - PATTERN_END -}; +static unsigned char bits_left[N_LEDS]; +static unsigned char *pattern_data[N_LEDS]; +static unsigned char current_bit[N_LEDS]; -pattern_t off_pattern[] = { - { 0, 0x1 }, - PATTERN_END +static unsigned char off_pattern[] = { + 0b00000000, }; -pattern_t on1_pattern[] = { - { 1, 1 }, - { 0, 2 }, - { 1, 1 }, - { 0, 8 }, - { 1, 1 }, - { 0, 8 }, - PATTERN_END -}; - -static void led_set_mode(unsigned char n, unsigned char mode) +void led_set_pattern(unsigned char led, unsigned char bits_len, + unsigned char bits_start, + unsigned char *data) { - switch (n) { - case 0: pwmled_on_off(mode); break; - case 1: status_led_on_off(mode); break; + if (!bits_len) { + led_set_pattern(led, 8, 0, off_pattern); + } else { + bits_left[led] = bits_len-1; + current_bit[led] = bits_start; + pattern_data[led] = data; } } -void led_set_pattern(unsigned char n, pattern_t *pattern) +void led_set_number_pattern(unsigned char led, unsigned char num, + unsigned char inv) { - if (!pattern) - pattern = off_pattern; - - led_patterns[n] = pattern; + static unsigned char pattern_num[] = { + 0b00100000, /* 10 */ + 0b10000010, /* 8,9 */ + 0b00001000, /* 7 */ + 0b00100000, /* 6 */ + 0b10000010, /* 4,5 */ + 0b00001000, /* 3 */ + 0b00100000, /* 2 */ + 0b10000000, /* 1 */ + 0b00000000, + }; + + static unsigned char pattern_invnum[] = { + 0b11011111, /* 10 */ + 0b01111101, /* 8,9 */ + 0b11110111, /* 7 */ + 0b11011111, /* 6 */ + 0b01111101, /* 4,5 */ + 0b11110111, /* 3 */ + 0b11011111, /* 2 */ + 0b01111111, /* 1 */ + 0b11111111, + }; + + unsigned char bits_len, bits_remaining; + + if (num > 10) + num = 10; - led_counters[n] = pattern->duration; - led_set_mode(n, pattern->mode); + bits_len = 6*num + 12; + bits_remaining = 9*8 - bits_len; + log_byte(0x88); + log_byte(bits_len); + log_byte(bits_remaining & 7); + log_byte(bits_remaining >> 3); + log_flush(); + led_set_pattern(led, bits_len, bits_remaining & 7, + inv ? pattern_invnum + (bits_remaining >> 3) + : pattern_num + (bits_remaining >> 3)); } -void init_pattern() +static void inline pattern_select(unsigned char n) { - unsigned char i; - - for (i = 0; i < N_LEDS; i++) - led_set_pattern(i, NULL); + switch(n) { + case 0: pwmled_pattern_select(n); + break; + case 1: status_led_pattern_select(n); + break; + } } -pattern_t *number_pattern(unsigned char num, unsigned char inv) +static void inline led_set_mode(unsigned char n, unsigned char mode) { - if (num >= 10) - num = 10; - - if (inv) { - return pattern_invnum - + sizeof(pattern_invnum)/sizeof(pattern_t) - - 2 - 2*num; - } else { - return pattern_num - + sizeof(pattern_num)/sizeof(pattern_t) - - 2 - 2*num; + switch (n) { + case 0: pwmled_on_off(mode); break; + case 1: status_led_on_off(mode); log_byte(mode); log_flush(); break; } } -static pattern_t *pattern_select(unsigned char n) +void patterns_next_tick() { - switch(n) { - case 0: return pwmled_pattern_select(); - case 1: return status_led_pattern_select(); - default: return NULL; + unsigned char i; + + for (i = 0; i < N_LEDS; i++) { + if (!bits_left[i]) { + pattern_select(i); + } else { + bits_left[i]--; + current_bit[i]++; + if (current_bit[i] >= 8) { + current_bit[i] = 0; + pattern_data[i]++; + } + } + + led_set_mode(i, *(pattern_data[i]) & (1 << (7 - current_bit[i])) + ? 1 : 0); } } -void pattern_reload() +void init_pattern() { unsigned char i; for (i = 0; i < N_LEDS; i++) - led_set_pattern(i, pattern_select(i)); + led_set_pattern(i, 0, 0, NULL); } -static void inline pattern_finished(unsigned char n) -{ - led_patterns[n] = NULL; - led_set_pattern(n, pattern_select(n)); -} - -void patterns_next_tick() +void pattern_reload() { unsigned char i; - for (i = 0; i < N_LEDS; i++) { - if (!led_patterns[i]) { - pattern_finished(i); - continue; - } - - if (--led_counters[i] == 0) { - pattern_t *p = led_patterns[i]; - p++; - if (p->duration == 0) { // END - /* Keep the last state, wait for others */ - pattern_finished(i); - continue; - } - led_set_pattern(i, p); - } + for (i = 0; i < N_LEDS; i++) + bits_left[i] = 0; - } + patterns_next_tick(); }