Statistics
| Branch: | Revision:

root / toolbox / led.c @ 215b2fa6

History | View | Annotate | Download (1.29 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
    OCR0A = OCR+1;
50
  } else {
51
    OCR0A = OCR;
52
  }
53
  ms++;
54
  if (ms == blink_period) {
55
    blink();
56
    if (blink_count == 0) {
57
      TCCR0B = 0;
58
    }
59
    ms = 0;
60
  }
61
}
62

    
63
void led_blink_start(unsigned int period_ms, char n_times, enum color_t color) {
64

    
65
  ms = 0;
66
  error = 0;
67

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

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

    
78
}
79

    
80
char led_blink_done() {
81
  return blink_count == 0;
82
}