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 |
} |