1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
/************************************************************************/
/* */
/* Decode DCF77 Time Information */
/* */
/* Author: Peter Dannegger */
/* danni@specs.de */
/* */
/************************************************************************/
#include "main.h"
#include "clock.h"
#include "timebase.h"
#include "dcf77.h"
u8 code BITNO[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // minute
0xFF, // parity
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, // hour
0xFF, // parity
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, // day
0x30, 0x31, 0x32, // weekday
0x40, 0x41, 0x42, 0x43, 0x44, // month
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, // year
0xFF }; // parity
u8 code BMASK[] = { 1, 2, 4, 8, 10, 20, 40, 80 };
struct time newtime;
u8 dcf77error = 0;
u8 synchronize = 0; // successful recieved
void decode_dcf77( u8 pulse )
{
static u8 parity = 0;
u8 i;
u8 *d;
i = newtime.second - 21;
if( i >= sizeof( BITNO )) // only bit 21 ... 58
return;
parity ^= pulse; // calculate parity
i = LPM(&BITNO[i]);
if( i == 0xFF ){ // test parity
if( parity )
dcf77error = 1;
parity = 0;
return;
}
d = (u8 *)&newtime.minute + (i >> 4); // byte address
i &= 0x0F; // bit number
if( i == 0 )
*d = 0; // clear all, if lsb
if( pulse )
*d += LPM(&BMASK[i]); // set bit
}
void scan_dcf77( void )
{
if( dcf77_pulse ){
if( dcf77_pulse > 3 && dcf77_pulse < 8 ){
decode_dcf77( 0 );
}else{
if( dcf77_pulse > 10 && dcf77_pulse < 14 ){
decode_dcf77( 1 );
}else{
dcf77error = 1;
}
}
dcf77_pulse = 0;
}
if( dcf77_period ){
if( newtime.second < 60 )
newtime.second++;
if( dcf77_period > 120 && dcf77_period < 140 ){
if( dcf77error == 0 && newtime.second == 59 ){
synchronize = 0xFF;
sync_sec();
time.second = 0;
time.minute = newtime.minute;
time.hour = newtime.hour;
time.wday = newtime.wday;
time.day = newtime.day;
time.month = newtime.month;
time.year = newtime.year;
}
newtime.second = 0;
dcf77error = 0;
}else{
if( dcf77_period < 60 || dcf77_period > 70 )
dcf77error = 1;
}
dcf77_period = 0;
}
}
|