Statistics
| Branch: | Revision:

root / toolbox / led.c @ 1085ef77

History | View | Annotate | Download (1.27 KB)

1
#include "led.h"
2
#include <avr/io.h>
3
#include <avr/interrupt.h>
4

    
5
#define PRESCALE 64
6
#define CLOCK_SEL 3
7

    
8
/* F_CPU / PRESCALE = OCR * 1000 + ERROR */
9
#define OCR (F_CPU / PRESCALE / 1000UL)
10
#define ERROR (F_CPU / PRESCALE - OCR * 1000UL)
11

    
12
char blink_count;
13
enum color_t blink_color;
14
uint16_t blink_period;
15

    
16
uint16_t ms;
17
uint16_t error;
18

    
19
static void led_color(enum color_t color) {
20
  switch (color) {
21
    case OFF:
22
      led_off();
23
      break;
24
    case RED:
25
      led_red();
26
      break;
27
    case YELLOW:
28
      led_yellow();
29
      break;
30
    case GREEN:
31
      led_green();
32
      break;
33
  }
34
}
35

    
36
static void blink() {
37
  blink_count--;
38
  if (blink_count % 2) {
39
    led_color(blink_color);
40
  } else {
41
    led_off();
42
  }
43
}
44

    
45
ISR(TIMER0_COMPA_vect) {
46
  error += ERROR;
47
  if (error >= 1000) {
48
    error -= 1000;
49
  } else {
50
    ms++;
51
    if (ms == blink_period) {
52
      blink();
53
      if (blink_count == 0) {
54
        TCCR0B = 0;
55
      }
56
      ms = 0;
57
    }
58
  }
59
}
60

    
61
void led_blink_start(unsigned int period_ms, char n_times, enum color_t color) {
62

    
63
  ms = 0;
64
  error = 0;
65

    
66
  blink_count = n_times*2-1;
67
  blink_period = period_ms/2;
68
  blink_color = color;
69
  led_color(color);
70

    
71
  OCR0A = OCR;
72
  TIMSK = _BV(OCIE0A);
73
  TCCR0A = _BV(WGM01);
74
  TCCR0B = CLOCK_SEL;
75

    
76
}
77

    
78
char led_blink_done() {
79
  return blink_count == 0;
80
}