summaryrefslogtreecommitdiff
path: root/dcf77.c
blob: 91ae618a15aa479aa3ae747fa0c649838673c745 (plain)
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;
  }
}