+/* ============ Status LED blinking =================================== */
+static unsigned char blink_on_time, blink_off_time, n_blinks;
+static unsigned char blink_counter;
+
+static unsigned char battery_level()
+{
+ unsigned char i, adc8;
+
+ // NOTE: we use 8-bit value only, so we don't need lock to protect
+ // us against concurrently running ADC IRQ handler:
+ adc8 = batt_off >> 8;
+
+ for (i = 0; i < BATT_N_LEVELS; i++)
+ if (batt_levels[i] > adc8)
+ break;
+
+ return i;
+}
+
+static void status_led_next_pattern()
+{
+ static unsigned char battery_exhausted;
+ static unsigned char display_power_level;
+
+ if (display_power_level) {
+ n_blinks = power_level + 1;
+ if (batt_on >> 8 == batt_off >> 8) { // load unplugged
+ n_blinks = 2 * n_blinks;
+ blink_on_time = 0;
+ blink_off_time = 0;
+ } else {
+ blink_on_time = 2;
+ blink_off_time = 2;
+ }
+ } else {
+ unsigned char b_level = battery_level();
+ if (b_level) {
+ battery_exhausted = 0;
+ } else if (battery_exhausted) {
+ if (!--battery_exhausted)
+ power_down();
+ } else {
+ battery_exhausted = LED_BATTEMPTY_COUNT;
+ }
+
+ n_blinks = b_level + 1;
+ blink_on_time = 4;
+ blink_off_time = 0;
+ }
+
+ blink_counter = 12;
+ display_power_level = !display_power_level;
+}
+
+static void timer_blink()
+{
+ if (blink_counter) {
+ blink_counter--;
+ } else if (!status_led_is_on()) {
+ status_led_on();
+ blink_counter = blink_on_time;
+ } else if (n_blinks) {
+ --n_blinks;
+ status_led_off();
+ blink_counter = blink_off_time;
+ } else {
+ status_led_next_pattern();
+ }
+}
+