diff options
Diffstat (limited to 'src/inc/int/dcf77/clock.c')
-rwxr-xr-x | src/inc/int/dcf77/clock.c | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/src/inc/int/dcf77/clock.c b/src/inc/int/dcf77/clock.c new file mode 100755 index 0000000..75f33fe --- /dev/null +++ b/src/inc/int/dcf77/clock.c | |||
@@ -0,0 +1,157 @@ | |||
1 | #include "clock.h" | ||
2 | |||
3 | |||
4 | // returns -1 on error | ||
5 | unsigned char getBits(const DCF start, const char len, const DCF pbit) | ||
6 | { | ||
7 | static const unsigned char mult[] = {1, 2, 4, 8, 10, 20 ,40 ,80}; | ||
8 | /// unsigned char p = 1; //parity | ||
9 | unsigned char r = 0; // retval | ||
10 | unsigned char i; | ||
11 | for(i=0; i<len; i++) | ||
12 | { | ||
13 | r += dcf77[start+i].bit * mult[i]; | ||
14 | /// if(dcf77[start+i].bit) | ||
15 | /// p ^= 1; | ||
16 | } | ||
17 | |||
18 | // 1110011 | ||
19 | // 001000 | ||
20 | |||
21 | // 8 | ||
22 | // 72 | ||
23 | |||
24 | /// if((pbit != DCF_FIRST) && (dcf77[pbit].bit != p)) | ||
25 | /// return -1; | ||
26 | /// else | ||
27 | return r; | ||
28 | } | ||
29 | |||
30 | void set_dcf_value() | ||
31 | { | ||
32 | // check for parity | ||
33 | /// if | ||
34 | /// ( | ||
35 | /// (dcf77[DCF_FIRST].bit != 0 ) | | ||
36 | /// (dcf77[DCF_START].bit != 1 ) | | ||
37 | /// (getBits(DCF_MIN, 7, DCF_MINP) == -1) | | ||
38 | /// (getBits(DCF_MIN, 7, DCF_START) > 59) | | ||
39 | /// (getBits(DCF_HOUR, 6, DCF_HOURP) == -1) | ||
40 | /// ) return; | ||
41 | |||
42 | // set new time | ||
43 | t_current.m = (getBits(DCF_MIN, 7, DCF_START)) - 1; | ||
44 | t_current.h = (getBits(DCF_HOUR, 6, DCF_START)); | ||
45 | t_current.dd = (getBits(DCF_DAY, 6, DCF_START)); | ||
46 | t_current.wd = (getBits(DCF_WEEKDAY, 3, DCF_START)); | ||
47 | t_current.mm = (getBits(DCF_MONTH, 5, DCF_START)); | ||
48 | t_current.yy = (getBits(DCF_YEAR, 8, DCF_START)); | ||
49 | } | ||
50 | |||
51 | // 7372800/a=10000 | ||
52 | // 115200 / a * x = 10000 | ||
53 | // 7372800/8/150 | ||
54 | ISR(TIMER0_COMP_vect) // called 10000 times per second (12000000/8/150) | ||
55 | { | ||
56 | //cli(); | ||
57 | // F_CPU / PRESCALER / (OCR0 + 1) | ||
58 | if(++t_current.us >= 10) // one u-second | ||
59 | { | ||
60 | t_current.us = 0; // restart | ||
61 | // interval length of dcf77 can be greater than 1000 ms... count it! | ||
62 | ++interval; | ||
63 | |||
64 | /* | ||
65 | cli(); | ||
66 | if(t_current.ms <= 500) | ||
67 | { OCR1A = 50 + (200 - (t_current.ms / 3)); } | ||
68 | else | ||
69 | { OCR1A = 50 + (200 - ((1000 - t_current.ms) / 3)); } | ||
70 | sei(); | ||
71 | */ | ||
72 | |||
73 | if(++t_current.ms >= 1000) // one second | ||
74 | { | ||
75 | t_current.ms = 0; // restart | ||
76 | if(++t_current.s > 59) // one minute | ||
77 | { | ||
78 | t_current.s = 0; // restart | ||
79 | if(++t_current.m > 59) // one hour | ||
80 | { | ||
81 | t_current.m = 0; // restart | ||
82 | if(++t_current.h > 23) // one day | ||
83 | { | ||
84 | t_current.h = 0; // restart | ||
85 | t_current.dd++; | ||
86 | } | ||
87 | } | ||
88 | } | ||
89 | } | ||
90 | } | ||
91 | //sei(); | ||
92 | } | ||
93 | |||
94 | ISR(INT0_vect) | ||
95 | { | ||
96 | /// stdout_put_int(interval, uart_putc); | ||
97 | /// stdout_put_string("INT0 call\n", uart_putc); | ||
98 | cli(); | ||
99 | if(INT0_CONTROL == INT0_RISING_EDGE) | ||
100 | { | ||
101 | if(interval > 1000 && interval < 2000) // 59th second - no rising edge at the beginning | ||
102 | { | ||
103 | /// if(dcf77_bit == 59) // check if every bit has been transfered | ||
104 | set_dcf_value(); // completely received- apply new time data | ||
105 | |||
106 | // 59th second: synchronize with receiver... | ||
107 | dcf77_bit = 0; | ||
108 | TCNT0 = 0; | ||
109 | t_current.s = 0; | ||
110 | t_current.ms = 0; | ||
111 | t_current.us = 0; | ||
112 | } | ||
113 | INT0_CONTROL = INT0_FALLING_EDGE; | ||
114 | } | ||
115 | else // INT0_FALLING_EDGE | ||
116 | { | ||
117 | dcf77[dcf77_bit++].bit = interval >= 200 ? 1 : 0; | ||
118 | lastinterval = interval; | ||
119 | |||
120 | INT0_CONTROL = INT0_RISING_EDGE; | ||
121 | } | ||
122 | |||
123 | interval = 0; // reset interval to count next interval | ||
124 | sei(); | ||
125 | } | ||
126 | |||
127 | |||
128 | void timer_init() | ||
129 | { | ||
130 | // 7372800/8 | ||
131 | DDRD &= ~((1<<PD2) | (1<<PD3)); // make INT0 and INT1 input-pins | ||
132 | |||
133 | // Prescaler... | ||
134 | TCCR0 = (0<<CS02) | (1<<CS01) | (0<<CS00) | (1<<WGM01); | ||
135 | // output compare... | ||
136 | OCR0 = 149; | ||
137 | //OCR0 = 152 - 1; | ||
138 | //TCCR0 |= (0<<WGM01) | (1<<WGM01); | ||
139 | |||
140 | // ICNC1 (Input Capture Noise Canceler (4 CKs) Timer/Counter 1 | ||
141 | // ICES1 (Input Capture Edge Select Timer/Counter 1) - 1:increasing 0:falling | ||
142 | // CSx: set prescaler (010 means 8) | ||
143 | /// TCCR1B = (1<<ICNC1) | (1<<ICES1) | (0<<CS12) | (1<<CS11) | (0<<CS10); | ||
144 | // OCIE0: Output Compare Match Interrupt Enable | ||
145 | // TICIE: Timer/Counter Input Capture Interrupt Enable | ||
146 | TIMSK |= (1<<OCIE0); | ||
147 | |||
148 | // interrupts_init... | ||
149 | // General Interrupt Mask Register (enables interrupts) | ||
150 | //GIMSK |= (1<<INT0); | ||
151 | GICR |= (1<<INT0); | ||
152 | // MCU Control Register (controls CPU-behaviours like interrupts & sleepmode) | ||
153 | //MCUCR |= (0<<ISC01) | (1<<ISC00); // any logical change generates interrupt | ||
154 | INT0_CONTROL = INT0_RISING_EDGE; // going to toggle int0-behaviour | ||
155 | /// loworhigh.bit = 0; | ||
156 | } | ||
157 | |||