Created
September 29, 2014 08:22
-
-
Save matthijskooijman/6f336497b4ad5741ff08 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 1 "C:\\Documents and Settings\\STEFANOD\\Documenti\\Arduino\\libraries\\dcf77_library\\dcf77.cpp" | |
# 1 "/arduino-1.5.7//" | |
# 1 "<command-line>" | |
# 1 "C:\\Documents and Settings\\STEFANOD\\Documenti\\Arduino\\libraries\\dcf77_library\\dcf77.cpp" | |
# 19 "C:\\Documents and Settings\\STEFANOD\\Documenti\\Arduino\\libraries\\dcf77_library\\dcf77.cpp" | |
# 1 "C:\\Documents and Settings\\STEFANOD\\Documenti\\Arduino\\libraries\\dcf77_library/dcf77.h" 1 | |
# 22 "C:\\Documents and Settings\\STEFANOD\\Documenti\\Arduino\\libraries\\dcf77_library/dcf77.h" | |
# 1 "/arduino-1.5.7/hardware/tools/avr/lib/gcc/avr/4.8.1/include/stdint.h" 1 3 4 | |
# 9 "/arduino-1.5.7/hardware/tools/avr/lib/gcc/avr/4.8.1/include/stdint.h" 3 4 | |
# 1 "/arduino-1.5.7/hardware/tools/avr/avr/include/stdint.h" 1 3 4 | |
# 121 "/arduino-1.5.7/hardware/tools/avr/avr/include/stdint.h" 3 4 | |
typedef signed int int8_t __attribute__((__mode__(__QI__))); | |
typedef unsigned int uint8_t __attribute__((__mode__(__QI__))); | |
typedef signed int int16_t __attribute__ ((__mode__ (__HI__))); | |
typedef unsigned int uint16_t __attribute__ ((__mode__ (__HI__))); | |
typedef signed int int32_t __attribute__ ((__mode__ (__SI__))); | |
typedef unsigned int uint32_t __attribute__ ((__mode__ (__SI__))); | |
typedef signed int int64_t __attribute__((__mode__(__DI__))); | |
typedef unsigned int uint64_t __attribute__((__mode__(__DI__))); | |
# 142 "/arduino-1.5.7/hardware/tools/avr/avr/include/stdint.h" 3 4 | |
typedef int16_t intptr_t; | |
typedef uint16_t uintptr_t; | |
# 159 "/arduino-1.5.7/hardware/tools/avr/avr/include/stdint.h" 3 4 | |
typedef int8_t int_least8_t; | |
typedef uint8_t uint_least8_t; | |
typedef int16_t int_least16_t; | |
typedef uint16_t uint_least16_t; | |
typedef int32_t int_least32_t; | |
typedef uint32_t uint_least32_t; | |
typedef int64_t int_least64_t; | |
typedef uint64_t uint_least64_t; | |
# 213 "/arduino-1.5.7/hardware/tools/avr/avr/include/stdint.h" 3 4 | |
typedef int8_t int_fast8_t; | |
typedef uint8_t uint_fast8_t; | |
typedef int16_t int_fast16_t; | |
typedef uint16_t uint_fast16_t; | |
typedef int32_t int_fast32_t; | |
typedef uint32_t uint_fast32_t; | |
typedef int64_t int_fast64_t; | |
typedef uint64_t uint_fast64_t; | |
# 273 "/arduino-1.5.7/hardware/tools/avr/avr/include/stdint.h" 3 4 | |
typedef int64_t intmax_t; | |
typedef uint64_t uintmax_t; | |
# 10 "/arduino-1.5.7/hardware/tools/avr/lib/gcc/avr/4.8.1/include/stdint.h" 2 3 4 | |
# 23 "C:\\Documents and Settings\\STEFANOD\\Documenti\\Arduino\\libraries\\dcf77_library/dcf77.h" 2 | |
# 1 "C:\\Documents and Settings\\STEFANOD\\Desktop\\TMP\\clock\\arduino-1.5.7\\hardware\\arduino\\avr\\cores\\arduino/Arduino.h" 1 | |
# 23 "C:\\Documents and Settings\\STEFANOD\\Desktop\\TMP\\clock\\arduino-1.5.7\\hardware\\arduino\\avr\\cores\\arduino/Arduino.h" | |
# 1 "/arduino-1.5.7/hardware/tools/avr/avr/include/stdlib.h" 1 3 | |
# 47 "/arduino-1.5.7/hardware/tools/avr/avr/include/stdlib.h" 3 | |
# 1 "/arduino-1.5.7/hardware/tools/avr/lib/gcc/avr/4.8.1/include/stddef.h" 1 3 4 | |
# 212 "/arduino-1.5.7/hardware/tools/avr/lib/gcc/avr/4.8.1/include/stddef.h" 3 4 | |
typedef unsigned int size_t; | |
# 48 "/arduino-1.5.7/hardware/tools/avr/avr/include/stdlib.h" 2 3 | |
extern "C" { | |
# 68 "/arduino-1.5.7/hardware/tools/avr/avr/include/stdlib.h" 3 | |
typedef struct { | |
int quot; | |
int rem; | |
} div_t; | |
typedef struct { | |
long quot; | |
long rem; | |
} ldiv_t; | |
typedef int (*__compar_fn_t)(const void *, const void *); | |
# 114 "/arduino-1.5.7/hardware/tools/avr/avr/include/stdlib.h" 3 | |
extern void abort(void) __attribute__((__noreturn__)); | |
extern int abs(int __i) __attribute__((__const__)); | |
# 128 "/arduino-1.5.7/hardware/tools/avr/avr/include/stdlib.h" 3 | |
extern long labs(long __i) __attribute__((__const__)); | |
# 151 "/arduino-1.5.7/hardware/tools/avr/avr/include/stdlib.h" 3 | |
extern void *bsearch(const void *__key, const void *__base, size_t __nmemb, | |
size_t __size, int (*__compar)(const void *, const void *)); | |
extern div_t div(int __num, int __denom) __asm__("__divmodhi4") __attribute__((__const__)); | |
extern ldiv_t ldiv(long __num, long __denom) __asm__("__divmodsi4") __attribute__((__const__)); | |
# 183 "/arduino-1.5.7/hardware/tools/avr/avr/include/stdlib.h" 3 | |
extern void qsort(void *__base, size_t __nmemb, size_t __size, | |
__compar_fn_t __compar); | |
# 216 "/arduino-1.5.7/hardware/tools/avr/avr/include/stdlib.h" 3 | |
extern long strtol(const char *__nptr, char **__endptr, int __base); | |
# 250 "/arduino-1.5.7/hardware/tools/avr/avr/include/stdlib.h" 3 | |
extern unsigned long strtoul(const char *__nptr, char **__endptr, int __base); | |
# 262 "/arduino-1.5.7/hardware/tools/avr/avr/include/stdlib.h" 3 | |
extern long atol(const char *__s) __attribute__((__pure__)); | |
# 274 "/arduino-1.5.7/hardware/tools/avr/avr/include/stdlib.h" 3 | |
extern int atoi(const char *__s) __attribute__((__pure__)); | |
# 286 "/arduino-1.5.7/hardware/tools/avr/avr/include/stdlib.h" 3 | |
extern void exit(int __status) __attribute__((__noreturn__)); | |
# 298 "/arduino-1.5.7/hardware/tools/avr/avr/include/stdlib.h" 3 | |
extern void *malloc(size_t __size) __attribute__((__malloc__)); | |
extern void free(void *__ptr); | |
extern size_t __malloc_margin; | |
extern char *__malloc_heap_start; | |
extern char *__malloc_heap_end; | |
extern void *calloc(size_t __nele, size_t __size) __attribute__((__malloc__)); | |
# 346 "/arduino-1.5.7/hardware/tools/avr/avr/include/stdlib.h" 3 | |
extern void *realloc(void *__ptr, size_t __size) __attribute__((__malloc__)); | |
extern double strtod(const char *__nptr, char **__endptr); | |
extern double atof(const char *__nptr); | |
# 372 "/arduino-1.5.7/hardware/tools/avr/avr/include/stdlib.h" 3 | |
extern int rand(void); | |
extern void srand(unsigned int __seed); | |
extern int rand_r(unsigned long *__ctx); | |
# 417 "/arduino-1.5.7/hardware/tools/avr/avr/include/stdlib.h" 3 | |
extern __inline__ | |
char *itoa (int __val, char *__s, int __radix) | |
{ | |
if (!__builtin_constant_p (__radix)) { | |
extern char *__itoa (int, char *, int); | |
return __itoa (__val, __s, __radix); | |
} else if (__radix < 2 || __radix > 36) { | |
*__s = 0; | |
return __s; | |
} else { | |
extern char *__itoa_ncheck (int, char *, unsigned char); | |
return __itoa_ncheck (__val, __s, __radix); | |
} | |
} | |
# 462 "/arduino-1.5.7/hardware/tools/avr/avr/include/stdlib.h" 3 | |
extern __inline__ | |
char *ltoa (long __val, char *__s, int __radix) | |
{ | |
if (!__builtin_constant_p (__radix)) { | |
extern char *__ltoa (long, char *, int); | |
return __ltoa (__val, __s, __radix); | |
} else if (__radix < 2 || __radix > 36) { | |
*__s = 0; | |
return __s; | |
} else { | |
extern char *__ltoa_ncheck (long, char *, unsigned char); | |
return __ltoa_ncheck (__val, __s, __radix); | |
} | |
} | |
# 505 "/arduino-1.5.7/hardware/tools/avr/avr/include/stdlib.h" 3 | |
extern __inline__ | |
char *utoa (unsigned int __val, char *__s, int __radix) | |
{ | |
if (!__builtin_constant_p (__radix)) { | |
extern char *__utoa (unsigned int, char *, int); | |
return __utoa (__val, __s, __radix); | |
} else if (__radix < 2 || __radix > 36) { | |
*__s = 0; | |
return __s; | |
} else { | |
extern char *__utoa_ncheck (unsigned int, char *, unsigned char); | |
return __utoa_ncheck (__val, __s, __radix); | |
} | |
} | |
# 547 "/arduino-1.5.7/hardware/tools/avr/avr/include/stdlib.h" 3 | |
extern __inline__ | |
char *ultoa (unsigned long __val, char *__s, int __radix) | |
{ | |
if (!__builtin_constant_p (__radix)) { | |
extern char *__ultoa (unsigned long, char *, int); | |
return __ultoa (__val, __s, __radix); | |
} else if (__radix < 2 || __radix > 36) { | |
*__s = 0; | |
return __s; | |
} else { | |
extern char *__ultoa_ncheck (unsigned long, char *, unsigned char); | |
return __ultoa_ncheck (__val, __s, __radix); | |
} | |
} | |
# 579 "/arduino-1.5.7/hardware/tools/avr/avr/include/stdlib.h" 3 | |
extern long random(void); | |
extern void srandom(unsigned long __seed); | |
extern long random_r(unsigned long *__ctx); | |
# 638 "/arduino-1.5.7/hardware/tools/avr/avr/include/stdlib.h" 3 | |
extern char *dtostre(double __val, char *__s, unsigned char __prec, | |
unsigned char __flags); | |
# 655 "/arduino-1.5.7/hardware/tools/avr/avr/include/stdlib.h" 3 | |
extern char *dtostrf(double __val, signed char __width, | |
unsigned char __prec, char *__s); | |
# 677 "/arduino-1.5.7/hardware/tools/avr/avr/include/stdlib.h" 3 | |
} | |
# 24 "C:\\Documents and Settings\\STEFANOD\\Desktop\\TMP\\clock\\arduino-1.5.7\\hardware\\arduino\\avr\\cores\\arduino/Arduino.h" 2 | |
# 1 "/arduino-1.5.7/hardware/tools/avr/lib/gcc/avr/4.8.1/include/stdbool.h" 1 3 4 | |
# 25 "C:\\Documents and Settings\\STEFANOD\\Desktop\\TMP\\clock\\arduino-1.5.7\\hardware\\arduino\\avr\\cores\\arduino/Arduino.h" 2 | |
# 1 "/arduino-1.5.7/hardware/tools/avr/avr/include/string.h" 1 3 | |
# 45 "/arduino-1.5.7/hardware/tools/avr/avr/include/string.h" 3 | |
# 1 "/arduino-1.5.7/hardware/tools/avr/lib/gcc/avr/4.8.1/include/stddef.h" 1 3 4 | |
# 46 "/arduino-1.5.7/hardware/tools/avr/avr/include/string.h" 2 3 | |
# 56 "/arduino-1.5.7/hardware/tools/avr/avr/include/string.h" 3 | |
extern "C" { | |
# 111 "/arduino-1.5.7/hardware/tools/avr/avr/include/string.h" 3 | |
extern int ffs (int __val) __attribute__((__const__)); | |
extern int ffsl (long __val) __attribute__((__const__)); | |
extern int ffsll (long long __val) __attribute__((__const__)); | |
extern void *memccpy(void *, const void *, int, size_t); | |
extern void *memchr(const void *, int, size_t) __attribute__((__pure__)); | |
extern int memcmp(const void *, const void *, size_t) __attribute__((__pure__)); | |
extern void *memcpy(void *, const void *, size_t); | |
extern void *memmem(const void *, size_t, const void *, size_t) __attribute__((__pure__)); | |
extern void *memmove(void *, const void *, size_t); | |
extern void *memrchr(const void *, int, size_t) __attribute__((__pure__)); | |
extern void *memset(void *, int, size_t); | |
extern char *strcat(char *, const char *); | |
extern char *strchr(const char *, int) __attribute__((__pure__)); | |
extern char *strchrnul(const char *, int) __attribute__((__pure__)); | |
extern int strcmp(const char *, const char *) __attribute__((__pure__)); | |
extern char *strcpy(char *, const char *); | |
extern int strcasecmp(const char *, const char *) __attribute__((__pure__)); | |
extern char *strcasestr(const char *, const char *) __attribute__((__pure__)); | |
extern size_t strcspn(const char *__s, const char *__reject) __attribute__((__pure__)); | |
extern char *strdup(const char *s1); | |
extern size_t strlcat(char *, const char *, size_t); | |
extern size_t strlcpy(char *, const char *, size_t); | |
extern size_t strlen(const char *) __attribute__((__pure__)); | |
extern char *strlwr(char *); | |
extern char *strncat(char *, const char *, size_t); | |
extern int strncmp(const char *, const char *, size_t) __attribute__((__pure__)); | |
extern char *strncpy(char *, const char *, size_t); | |
extern int strncasecmp(const char *, const char *, size_t) __attribute__((__pure__)); | |
extern size_t strnlen(const char *, size_t) __attribute__((__pure__)); | |
extern char *strpbrk(const char *__s, const char *__accept) __attribute__((__pure__)); | |
extern char *strrchr(const char *, int) __attribute__((__pure__)); | |
extern char *strrev(char *); | |
extern char *strsep(char **, const char *); | |
extern size_t strspn(const char *__s, const char *__accept) __attribute__((__pure__)); | |
extern char *strstr(const char *, const char *) __attribute__((__pure__)); | |
extern char *strtok(char *, const char *); | |
extern char *strtok_r(char *, const char *, char **); | |
extern char *strupr(char *); | |
} | |
# 26 "C:\\Documents and Settings\\STEFANOD\\Desktop\\TMP\\clock\\arduino-1.5.7\\hardware\\arduino\\avr\\cores\\arduino/Arduino.h" 2 | |
# 1 "/arduino-1.5.7/hardware/tools/avr/avr/include/math.h" 1 3 | |
# 121 "/arduino-1.5.7/hardware/tools/avr/avr/include/math.h" 3 | |
extern "C" { | |
extern double cos(double __x) __attribute__((__const__)); | |
extern double sin(double __x) __attribute__((__const__)); | |
extern double tan(double __x) __attribute__((__const__)); | |
extern double fabs(double __x) __attribute__((__const__)); | |
extern double fmod(double __x, double __y) __attribute__((__const__)); | |
# 168 "/arduino-1.5.7/hardware/tools/avr/avr/include/math.h" 3 | |
extern double modf(double __x, double *__iptr); | |
extern float modff (float __x, float *__iptr); | |
extern double sqrt(double __x) __attribute__((__const__)); | |
extern double cbrt(double __x) __attribute__((__const__)); | |
# 194 "/arduino-1.5.7/hardware/tools/avr/avr/include/math.h" 3 | |
extern double hypot (double __x, double __y) __attribute__((__const__)); | |
extern double square(double __x) __attribute__((__const__)); | |
extern double floor(double __x) __attribute__((__const__)); | |
extern double ceil(double __x) __attribute__((__const__)); | |
# 234 "/arduino-1.5.7/hardware/tools/avr/avr/include/math.h" 3 | |
extern double frexp(double __x, int *__pexp); | |
extern double ldexp(double __x, int __exp) __attribute__((__const__)); | |
extern double exp(double __x) __attribute__((__const__)); | |
extern double cosh(double __x) __attribute__((__const__)); | |
extern double sinh(double __x) __attribute__((__const__)); | |
extern double tanh(double __x) __attribute__((__const__)); | |
extern double acos(double __x) __attribute__((__const__)); | |
extern double asin(double __x) __attribute__((__const__)); | |
extern double atan(double __x) __attribute__((__const__)); | |
# 298 "/arduino-1.5.7/hardware/tools/avr/avr/include/math.h" 3 | |
extern double atan2(double __y, double __x) __attribute__((__const__)); | |
extern double log(double __x) __attribute__((__const__)); | |
extern double log10(double __x) __attribute__((__const__)); | |
extern double pow(double __x, double __y) __attribute__((__const__)); | |
extern int isnan(double __x) __attribute__((__const__)); | |
# 333 "/arduino-1.5.7/hardware/tools/avr/avr/include/math.h" 3 | |
extern int isinf(double __x) __attribute__((__const__)); | |
__attribute__((__const__)) static inline int isfinite (double __x) | |
{ | |
unsigned char __exp; | |
__asm__ ( | |
"mov %0, %C1 \n\t" | |
"lsl %0 \n\t" | |
"mov %0, %D1 \n\t" | |
"rol %0 " | |
: "=r" (__exp) | |
: "r" (__x) ); | |
return __exp != 0xff; | |
} | |
__attribute__((__const__)) static inline double copysign (double __x, double __y) | |
{ | |
__asm__ ( | |
"bst %D2, 7 \n\t" | |
"bld %D0, 7 " | |
: "=r" (__x) | |
: "0" (__x), "r" (__y) ); | |
return __x; | |
} | |
# 376 "/arduino-1.5.7/hardware/tools/avr/avr/include/math.h" 3 | |
extern int signbit (double __x) __attribute__((__const__)); | |
extern double fdim (double __x, double __y) __attribute__((__const__)); | |
# 392 "/arduino-1.5.7/hardware/tools/avr/avr/include/math.h" 3 | |
extern double fma (double __x, double __y, double __z) __attribute__((__const__)); | |
extern double fmax (double __x, double __y) __attribute__((__const__)); | |
extern double fmin (double __x, double __y) __attribute__((__const__)); | |
extern double trunc (double __x) __attribute__((__const__)); | |
# 426 "/arduino-1.5.7/hardware/tools/avr/avr/include/math.h" 3 | |
extern double round (double __x) __attribute__((__const__)); | |
# 439 "/arduino-1.5.7/hardware/tools/avr/avr/include/math.h" 3 | |
extern long lround (double __x) __attribute__((__const__)); | |
# 453 "/arduino-1.5.7/hardware/tools/avr/avr/include/math.h" 3 | |
extern long lrint (double __x) __attribute__((__const__)); | |
} | |
# 27 "C:\\Documents and Settings\\STEFANOD\\Desktop\\TMP\\clock\\arduino-1.5.7\\hardware\\arduino\\avr\\cores\\arduino/Arduino.h" 2 | |
# 1 "/arduino-1.5.7/hardware/tools/avr/avr/include/avr/pgmspace.h" 1 3 | |
# 86 "/arduino-1.5.7/hardware/tools/avr/avr/include/avr/pgmspace.h" 3 | |
# 1 "/arduino-1.5.7/hardware/tools/avr/avr/include/inttypes.h" 1 3 | |
# 77 "/arduino-1.5.7/hardware/tools/avr/avr/include/inttypes.h" 3 | |
typedef int32_t int_farptr_t; | |
typedef uint32_t uint_farptr_t; | |
# 87 "/arduino-1.5.7/hardware/tools/avr/avr/include/avr/pgmspace.h" 2 3 | |
# 1 "/arduino-1.5.7/hardware/tools/avr/lib/gcc/avr/4.8.1/include/stddef.h" 1 3 4 | |
# 88 "/arduino-1.5.7/hardware/tools/avr/avr/include/avr/pgmspace.h" 2 3 | |
# 1 "/arduino-1.5.7/hardware/tools/avr/avr/include/avr/io.h" 1 3 | |
# 99 "/arduino-1.5.7/hardware/tools/avr/avr/include/avr/io.h" 3 | |
# 1 "/arduino-1.5.7/hardware/tools/avr/avr/include/avr/sfr_defs.h" 1 3 | |
# 100 "/arduino-1.5.7/hardware/tools/avr/avr/include/avr/io.h" 2 3 | |
# 174 "/arduino-1.5.7/hardware/tools/avr/avr/include/avr/io.h" 3 | |
# 1 "/arduino-1.5.7/hardware/tools/avr/avr/include/avr/iom2560.h" 1 3 | |
# 38 "/arduino-1.5.7/hardware/tools/avr/avr/include/avr/iom2560.h" 3 | |
# 1 "/arduino-1.5.7/hardware/tools/avr/avr/include/avr/iomxx0_1.h" 1 3 | |
# 1613 "/arduino-1.5.7/hardware/tools/avr/avr/include/avr/iomxx0_1.h" 3 | |
# 1614 "/arduino-1.5.7/hardware/tools/avr/avr/include/avr/iomxx0_1.h" 3 | |
# 39 "/arduino-1.5.7/hardware/tools/avr/avr/include/avr/iom2560.h" 2 3 | |
# 175 "/arduino-1.5.7/hardware/tools/avr/avr/include/avr/io.h" 2 3 | |
# 606 "/arduino-1.5.7/hardware/tools/avr/avr/include/avr/io.h" 3 | |
# 1 "/arduino-1.5.7/hardware/tools/avr/avr/include/avr/portpins.h" 1 3 | |
# 607 "/arduino-1.5.7/hardware/tools/avr/avr/include/avr/io.h" 2 3 | |
# 1 "/arduino-1.5.7/hardware/tools/avr/avr/include/avr/common.h" 1 3 | |
# 609 "/arduino-1.5.7/hardware/tools/avr/avr/include/avr/io.h" 2 3 | |
# 1 "/arduino-1.5.7/hardware/tools/avr/avr/include/avr/version.h" 1 3 | |
# 611 "/arduino-1.5.7/hardware/tools/avr/avr/include/avr/io.h" 2 3 | |
# 1 "/arduino-1.5.7/hardware/tools/avr/avr/include/avr/fuse.h" 1 3 | |
# 239 "/arduino-1.5.7/hardware/tools/avr/avr/include/avr/fuse.h" 3 | |
typedef struct | |
{ | |
unsigned char low; | |
unsigned char high; | |
unsigned char extended; | |
} __fuse_t; | |
# 618 "/arduino-1.5.7/hardware/tools/avr/avr/include/avr/io.h" 2 3 | |
# 1 "/arduino-1.5.7/hardware/tools/avr/avr/include/avr/lock.h" 1 3 | |
# 621 "/arduino-1.5.7/hardware/tools/avr/avr/include/avr/io.h" 2 3 | |
# 89 "/arduino-1.5.7/hardware/tools/avr/avr/include/avr/pgmspace.h" 2 3 | |
# 112 "/arduino-1.5.7/hardware/tools/avr/avr/include/avr/pgmspace.h" 3 | |
extern "C" { | |
# 1137 "/arduino-1.5.7/hardware/tools/avr/avr/include/avr/pgmspace.h" 3 | |
extern const void * memchr_P(const void *, int __val, size_t __len) __attribute__((__const__)); | |
extern int memcmp_P(const void *, const void *, size_t) __attribute__((__pure__)); | |
extern void *memccpy_P(void *, const void *, int __val, size_t); | |
extern void *memcpy_P(void *, const void *, size_t); | |
extern void *memmem_P(const void *, size_t, const void *, size_t) __attribute__((__pure__)); | |
extern const void * memrchr_P(const void *, int __val, size_t __len) __attribute__((__const__)); | |
extern char *strcat_P(char *, const char *); | |
extern const char * strchr_P(const char *, int __val) __attribute__((__const__)); | |
extern const char * strchrnul_P(const char *, int __val) __attribute__((__const__)); | |
extern int strcmp_P(const char *, const char *) __attribute__((__pure__)); | |
extern char *strcpy_P(char *, const char *); | |
extern int strcasecmp_P(const char *, const char *) __attribute__((__pure__)); | |
extern char *strcasestr_P(const char *, const char *) __attribute__((__pure__)); | |
extern size_t strcspn_P(const char *__s, const char * __reject) __attribute__((__pure__)); | |
extern size_t strlcat_P (char *, const char *, size_t ); | |
extern size_t strlcpy_P (char *, const char *, size_t ); | |
extern size_t __strlen_P(const char *) __attribute__((__const__)); | |
extern size_t strnlen_P(const char *, size_t) __attribute__((__const__)); | |
extern int strncmp_P(const char *, const char *, size_t) __attribute__((__pure__)); | |
extern int strncasecmp_P(const char *, const char *, size_t) __attribute__((__pure__)); | |
extern char *strncat_P(char *, const char *, size_t); | |
extern char *strncpy_P(char *, const char *, size_t); | |
extern char *strpbrk_P(const char *__s, const char * __accept) __attribute__((__pure__)); | |
extern const char * strrchr_P(const char *, int __val) __attribute__((__const__)); | |
extern char *strsep_P(char **__sp, const char * __delim); | |
extern size_t strspn_P(const char *__s, const char * __accept) __attribute__((__pure__)); | |
extern char *strstr_P(const char *, const char *) __attribute__((__pure__)); | |
extern char *strtok_P(char *__s, const char * __delim); | |
extern char *strtok_rP(char *__s, const char * __delim, char **__last); | |
extern size_t strlen_PF (uint_farptr_t src) __attribute__((__const__)); | |
extern size_t strnlen_PF (uint_farptr_t src, size_t len) __attribute__((__const__)); | |
extern void *memcpy_PF (void *dest, uint_farptr_t src, size_t len); | |
extern char *strcpy_PF (char *dest, uint_farptr_t src); | |
extern char *strncpy_PF (char *dest, uint_farptr_t src, size_t len); | |
extern char *strcat_PF (char *dest, uint_farptr_t src); | |
extern size_t strlcat_PF (char *dst, uint_farptr_t src, size_t siz); | |
extern char *strncat_PF (char *dest, uint_farptr_t src, size_t len); | |
extern int strcmp_PF (const char *s1, uint_farptr_t s2) __attribute__((__pure__)); | |
extern int strncmp_PF (const char *s1, uint_farptr_t s2, size_t n) __attribute__((__pure__)); | |
extern int strcasecmp_PF (const char *s1, uint_farptr_t s2) __attribute__((__pure__)); | |
extern int strncasecmp_PF (const char *s1, uint_farptr_t s2, size_t n) __attribute__((__pure__)); | |
extern char *strstr_PF (const char *s1, uint_farptr_t s2); | |
extern size_t strlcpy_PF (char *dst, uint_farptr_t src, size_t siz); | |
extern int memcmp_PF(const void *, uint_farptr_t, size_t) __attribute__((__pure__)); | |
__attribute__((__always_inline__)) static inline size_t strlen_P(const char * s); | |
static inline size_t strlen_P(const char *s) { | |
return __builtin_constant_p(__builtin_strlen(s)) | |
? __builtin_strlen(s) : __strlen_P(s); | |
} | |
} | |
# 29 "C:\\Documents and Settings\\STEFANOD\\Desktop\\TMP\\clock\\arduino-1.5.7\\hardware\\arduino\\avr\\cores\\arduino/Arduino.h" 2 | |
# 1 "/arduino-1.5.7/hardware/tools/avr/avr/include/avr/interrupt.h" 1 3 | |
# 31 "C:\\Documents and Settings\\STEFANOD\\Desktop\\TMP\\clock\\arduino-1.5.7\\hardware\\arduino\\avr\\cores\\arduino/Arduino.h" 2 | |
# 1 "C:\\Documents and Settings\\STEFANOD\\Desktop\\TMP\\clock\\arduino-1.5.7\\hardware\\arduino\\avr\\cores\\arduino/binary.h" 1 | |
# 33 "C:\\Documents and Settings\\STEFANOD\\Desktop\\TMP\\clock\\arduino-1.5.7\\hardware\\arduino\\avr\\cores\\arduino/Arduino.h" 2 | |
extern "C"{ | |
void yield(void); | |
# 113 "C:\\Documents and Settings\\STEFANOD\\Desktop\\TMP\\clock\\arduino-1.5.7\\hardware\\arduino\\avr\\cores\\arduino/Arduino.h" | |
typedef unsigned int word; | |
typedef uint8_t boolean; | |
typedef uint8_t byte; | |
void init(void); | |
void initVariant(void); | |
void pinMode(uint8_t, uint8_t); | |
void digitalWrite(uint8_t, uint8_t); | |
int digitalRead(uint8_t); | |
int analogRead(uint8_t); | |
void analogReference(uint8_t mode); | |
void analogWrite(uint8_t, int); | |
unsigned long millis(void); | |
unsigned long micros(void); | |
void delay(unsigned long); | |
void delayMicroseconds(unsigned int us); | |
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout); | |
void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val); | |
uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder); | |
void attachInterrupt(uint8_t, void (*)(void), int mode); | |
void detachInterrupt(uint8_t); | |
void setup(void); | |
void loop(void); | |
# 152 "C:\\Documents and Settings\\STEFANOD\\Desktop\\TMP\\clock\\arduino-1.5.7\\hardware\\arduino\\avr\\cores\\arduino/Arduino.h" | |
extern const uint16_t __attribute__((__progmem__)) port_to_mode_PGM[]; | |
extern const uint16_t __attribute__((__progmem__)) port_to_input_PGM[]; | |
extern const uint16_t __attribute__((__progmem__)) port_to_output_PGM[]; | |
extern const uint8_t __attribute__((__progmem__)) digital_pin_to_port_PGM[]; | |
extern const uint8_t __attribute__((__progmem__)) digital_pin_to_bit_mask_PGM[]; | |
extern const uint8_t __attribute__((__progmem__)) digital_pin_to_timer_PGM[]; | |
# 215 "C:\\Documents and Settings\\STEFANOD\\Desktop\\TMP\\clock\\arduino-1.5.7\\hardware\\arduino\\avr\\cores\\arduino/Arduino.h" | |
} | |
# 1 "C:\\Documents and Settings\\STEFANOD\\Desktop\\TMP\\clock\\arduino-1.5.7\\hardware\\arduino\\avr\\cores\\arduino/WCharacter.h" 1 | |
# 23 "C:\\Documents and Settings\\STEFANOD\\Desktop\\TMP\\clock\\arduino-1.5.7\\hardware\\arduino\\avr\\cores\\arduino/WCharacter.h" | |
# 1 "/arduino-1.5.7/hardware/tools/avr/avr/include/ctype.h" 1 3 | |
# 48 "/arduino-1.5.7/hardware/tools/avr/avr/include/ctype.h" 3 | |
extern "C" { | |
# 74 "/arduino-1.5.7/hardware/tools/avr/avr/include/ctype.h" 3 | |
extern int isalnum(int __c) __attribute__((__const__)); | |
extern int isalpha(int __c) __attribute__((__const__)); | |
extern int isascii(int __c) __attribute__((__const__)); | |
extern int isblank(int __c) __attribute__((__const__)); | |
extern int iscntrl(int __c) __attribute__((__const__)); | |
extern int isdigit(int __c) __attribute__((__const__)); | |
extern int isgraph(int __c) __attribute__((__const__)); | |
extern int islower(int __c) __attribute__((__const__)); | |
extern int isprint(int __c) __attribute__((__const__)); | |
extern int ispunct(int __c) __attribute__((__const__)); | |
extern int isspace(int __c) __attribute__((__const__)); | |
extern int isupper(int __c) __attribute__((__const__)); | |
extern int isxdigit(int __c) __attribute__((__const__)); | |
# 173 "/arduino-1.5.7/hardware/tools/avr/avr/include/ctype.h" 3 | |
extern int toascii(int __c) __attribute__((__const__)); | |
extern int tolower(int __c) __attribute__((__const__)); | |
extern int toupper(int __c) __attribute__((__const__)); | |
} | |
# 24 "C:\\Documents and Settings\\STEFANOD\\Desktop\\TMP\\clock\\arduino-1.5.7\\hardware\\arduino\\avr\\cores\\arduino/WCharacter.h" 2 | |
inline boolean isAlphaNumeric(int c) __attribute__((always_inline)); | |
inline boolean isAlpha(int c) __attribute__((always_inline)); | |
inline boolean isAscii(int c) __attribute__((always_inline)); | |
inline boolean isWhitespace(int c) __attribute__((always_inline)); | |
inline boolean isControl(int c) __attribute__((always_inline)); | |
inline boolean isDigit(int c) __attribute__((always_inline)); | |
inline boolean isGraph(int c) __attribute__((always_inline)); | |
inline boolean isLowerCase(int c) __attribute__((always_inline)); | |
inline boolean isPrintable(int c) __attribute__((always_inline)); | |
inline boolean isPunct(int c) __attribute__((always_inline)); | |
inline boolean isSpace(int c) __attribute__((always_inline)); | |
inline boolean isUpperCase(int c) __attribute__((always_inline)); | |
inline boolean isHexadecimalDigit(int c) __attribute__((always_inline)); | |
inline int toAscii(int c) __attribute__((always_inline)); | |
inline int toLowerCase(int c) __attribute__((always_inline)); | |
inline int toUpperCase(int c)__attribute__((always_inline)); | |
inline boolean isAlphaNumeric(int c) | |
{ | |
return ( isalnum(c) == 0 ? false : true); | |
} | |
inline boolean isAlpha(int c) | |
{ | |
return ( isalpha(c) == 0 ? false : true); | |
} | |
inline boolean isAscii(int c) | |
{ | |
return ( isascii (c) == 0 ? false : true); | |
} | |
inline boolean isWhitespace(int c) | |
{ | |
return ( isblank (c) == 0 ? false : true); | |
} | |
inline boolean isControl(int c) | |
{ | |
return ( iscntrl (c) == 0 ? false : true); | |
} | |
inline boolean isDigit(int c) | |
{ | |
return ( isdigit (c) == 0 ? false : true); | |
} | |
inline boolean isGraph(int c) | |
{ | |
return ( isgraph (c) == 0 ? false : true); | |
} | |
inline boolean isLowerCase(int c) | |
{ | |
return (islower (c) == 0 ? false : true); | |
} | |
inline boolean isPrintable(int c) | |
{ | |
return ( isprint (c) == 0 ? false : true); | |
} | |
inline boolean isPunct(int c) | |
{ | |
return ( ispunct (c) == 0 ? false : true); | |
} | |
inline boolean isSpace(int c) | |
{ | |
return ( isspace (c) == 0 ? false : true); | |
} | |
inline boolean isUpperCase(int c) | |
{ | |
return ( isupper (c) == 0 ? false : true); | |
} | |
inline boolean isHexadecimalDigit(int c) | |
{ | |
return ( isxdigit (c) == 0 ? false : true); | |
} | |
inline int toAscii(int c) | |
{ | |
return toascii (c); | |
} | |
# 156 "C:\\Documents and Settings\\STEFANOD\\Desktop\\TMP\\clock\\arduino-1.5.7\\hardware\\arduino\\avr\\cores\\arduino/WCharacter.h" | |
inline int toLowerCase(int c) | |
{ | |
return tolower (c); | |
} | |
inline int toUpperCase(int c) | |
{ | |
return toupper (c); | |
} | |
# 220 "C:\\Documents and Settings\\STEFANOD\\Desktop\\TMP\\clock\\arduino-1.5.7\\hardware\\arduino\\avr\\cores\\arduino/Arduino.h" 2 | |
# 1 "C:\\Documents and Settings\\STEFANOD\\Desktop\\TMP\\clock\\arduino-1.5.7\\hardware\\arduino\\avr\\cores\\arduino/WString.h" 1 | |
# 37 "C:\\Documents and Settings\\STEFANOD\\Desktop\\TMP\\clock\\arduino-1.5.7\\hardware\\arduino\\avr\\cores\\arduino/WString.h" | |
class __FlashStringHelper; | |
class StringSumHelper; | |
class String | |
{ | |
typedef void (String::*StringIfHelperType)() const; | |
void StringIfHelper() const {} | |
public: | |
String(const char *cstr = ""); | |
String(const String &str); | |
String(const __FlashStringHelper *str); | |
explicit String(char c); | |
explicit String(unsigned char, unsigned char base=10); | |
explicit String(int, unsigned char base=10); | |
explicit String(unsigned int, unsigned char base=10); | |
explicit String(long, unsigned char base=10); | |
explicit String(unsigned long, unsigned char base=10); | |
explicit String(float, unsigned char decimalPlaces=2); | |
explicit String(double, unsigned char decimalPlaces=2); | |
~String(void); | |
unsigned char reserve(unsigned int size); | |
inline unsigned int length(void) const {return len;} | |
String & operator = (const String &rhs); | |
String & operator = (const char *cstr); | |
String & operator = (const __FlashStringHelper *str); | |
# 99 "C:\\Documents and Settings\\STEFANOD\\Desktop\\TMP\\clock\\arduino-1.5.7\\hardware\\arduino\\avr\\cores\\arduino/WString.h" | |
unsigned char concat(const String &str); | |
unsigned char concat(const char *cstr); | |
unsigned char concat(char c); | |
unsigned char concat(unsigned char c); | |
unsigned char concat(int num); | |
unsigned char concat(unsigned int num); | |
unsigned char concat(long num); | |
unsigned char concat(unsigned long num); | |
unsigned char concat(float num); | |
unsigned char concat(double num); | |
unsigned char concat(const __FlashStringHelper * str); | |
String & operator += (const String &rhs) {concat(rhs); return (*this);} | |
String & operator += (const char *cstr) {concat(cstr); return (*this);} | |
String & operator += (char c) {concat(c); return (*this);} | |
String & operator += (unsigned char num) {concat(num); return (*this);} | |
String & operator += (int num) {concat(num); return (*this);} | |
String & operator += (unsigned int num) {concat(num); return (*this);} | |
String & operator += (long num) {concat(num); return (*this);} | |
String & operator += (unsigned long num) {concat(num); return (*this);} | |
String & operator += (float num) {concat(num); return (*this);} | |
String & operator += (double num) {concat(num); return (*this);} | |
String & operator += (const __FlashStringHelper *str){concat(str); return (*this);} | |
friend StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs); | |
friend StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr); | |
friend StringSumHelper & operator + (const StringSumHelper &lhs, char c); | |
friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num); | |
friend StringSumHelper & operator + (const StringSumHelper &lhs, int num); | |
friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num); | |
friend StringSumHelper & operator + (const StringSumHelper &lhs, long num); | |
friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num); | |
friend StringSumHelper & operator + (const StringSumHelper &lhs, float num); | |
friend StringSumHelper & operator + (const StringSumHelper &lhs, double num); | |
friend StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs); | |
operator StringIfHelperType() const { return buffer ? &String::StringIfHelper : 0; } | |
int compareTo(const String &s) const; | |
unsigned char equals(const String &s) const; | |
unsigned char equals(const char *cstr) const; | |
unsigned char operator == (const String &rhs) const {return equals(rhs);} | |
unsigned char operator == (const char *cstr) const {return equals(cstr);} | |
unsigned char operator != (const String &rhs) const {return !equals(rhs);} | |
unsigned char operator != (const char *cstr) const {return !equals(cstr);} | |
unsigned char operator < (const String &rhs) const; | |
unsigned char operator > (const String &rhs) const; | |
unsigned char operator <= (const String &rhs) const; | |
unsigned char operator >= (const String &rhs) const; | |
unsigned char equalsIgnoreCase(const String &s) const; | |
unsigned char startsWith( const String &prefix) const; | |
unsigned char startsWith(const String &prefix, unsigned int offset) const; | |
unsigned char endsWith(const String &suffix) const; | |
char charAt(unsigned int index) const; | |
void setCharAt(unsigned int index, char c); | |
char operator [] (unsigned int index) const; | |
char& operator [] (unsigned int index); | |
void getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index=0) const; | |
void toCharArray(char *buf, unsigned int bufsize, unsigned int index=0) const | |
{getBytes((unsigned char *)buf, bufsize, index);} | |
const char * c_str() const { return buffer; } | |
int indexOf( char ch ) const; | |
int indexOf( char ch, unsigned int fromIndex ) const; | |
int indexOf( const String &str ) const; | |
int indexOf( const String &str, unsigned int fromIndex ) const; | |
int lastIndexOf( char ch ) const; | |
int lastIndexOf( char ch, unsigned int fromIndex ) const; | |
int lastIndexOf( const String &str ) const; | |
int lastIndexOf( const String &str, unsigned int fromIndex ) const; | |
String substring( unsigned int beginIndex ) const { return substring(beginIndex, len); }; | |
String substring( unsigned int beginIndex, unsigned int endIndex ) const; | |
void replace(char find, char replace); | |
void replace(const String& find, const String& replace); | |
void remove(unsigned int index); | |
void remove(unsigned int index, unsigned int count); | |
void toLowerCase(void); | |
void toUpperCase(void); | |
void trim(void); | |
long toInt(void) const; | |
float toFloat(void) const; | |
protected: | |
char *buffer; | |
unsigned int capacity; | |
unsigned int len; | |
protected: | |
void init(void); | |
void invalidate(void); | |
unsigned char changeBuffer(unsigned int maxStrLen); | |
unsigned char concat(const char *cstr, unsigned int length); | |
String & copy(const char *cstr, unsigned int length); | |
String & copy(const __FlashStringHelper *pstr, unsigned int length); | |
}; | |
class StringSumHelper : public String | |
{ | |
public: | |
StringSumHelper(const String &s) : String(s) {} | |
StringSumHelper(const char *p) : String(p) {} | |
StringSumHelper(char c) : String(c) {} | |
StringSumHelper(unsigned char num) : String(num) {} | |
StringSumHelper(int num) : String(num) {} | |
StringSumHelper(unsigned int num) : String(num) {} | |
StringSumHelper(long num) : String(num) {} | |
StringSumHelper(unsigned long num) : String(num) {} | |
StringSumHelper(float num) : String(num) {} | |
StringSumHelper(double num) : String(num) {} | |
}; | |
# 221 "C:\\Documents and Settings\\STEFANOD\\Desktop\\TMP\\clock\\arduino-1.5.7\\hardware\\arduino\\avr\\cores\\arduino/Arduino.h" 2 | |
# 1 "C:\\Documents and Settings\\STEFANOD\\Desktop\\TMP\\clock\\arduino-1.5.7\\hardware\\arduino\\avr\\cores\\arduino/HardwareSerial.h" 1 | |
# 29 "C:\\Documents and Settings\\STEFANOD\\Desktop\\TMP\\clock\\arduino-1.5.7\\hardware\\arduino\\avr\\cores\\arduino/HardwareSerial.h" | |
# 1 "C:\\Documents and Settings\\STEFANOD\\Desktop\\TMP\\clock\\arduino-1.5.7\\hardware\\arduino\\avr\\cores\\arduino/Stream.h" 1 | |
# 26 "C:\\Documents and Settings\\STEFANOD\\Desktop\\TMP\\clock\\arduino-1.5.7\\hardware\\arduino\\avr\\cores\\arduino/Stream.h" | |
# 1 "C:\\Documents and Settings\\STEFANOD\\Desktop\\TMP\\clock\\arduino-1.5.7\\hardware\\arduino\\avr\\cores\\arduino/Print.h" 1 | |
# 24 "C:\\Documents and Settings\\STEFANOD\\Desktop\\TMP\\clock\\arduino-1.5.7\\hardware\\arduino\\avr\\cores\\arduino/Print.h" | |
# 1 "/arduino-1.5.7/hardware/tools/avr/avr/include/stdio.h" 1 3 | |
# 45 "/arduino-1.5.7/hardware/tools/avr/avr/include/stdio.h" 3 | |
# 1 "/arduino-1.5.7/hardware/tools/avr/lib/gcc/avr/4.8.1/include/stdarg.h" 1 3 4 | |
# 40 "/arduino-1.5.7/hardware/tools/avr/lib/gcc/avr/4.8.1/include/stdarg.h" 3 4 | |
typedef __builtin_va_list __gnuc_va_list; | |
# 98 "/arduino-1.5.7/hardware/tools/avr/lib/gcc/avr/4.8.1/include/stdarg.h" 3 4 | |
typedef __gnuc_va_list va_list; | |
# 46 "/arduino-1.5.7/hardware/tools/avr/avr/include/stdio.h" 2 3 | |
# 1 "/arduino-1.5.7/hardware/tools/avr/lib/gcc/avr/4.8.1/include/stddef.h" 1 3 4 | |
# 50 "/arduino-1.5.7/hardware/tools/avr/avr/include/stdio.h" 2 3 | |
# 242 "/arduino-1.5.7/hardware/tools/avr/avr/include/stdio.h" 3 | |
struct __file { | |
char *buf; | |
unsigned char unget; | |
uint8_t flags; | |
# 261 "/arduino-1.5.7/hardware/tools/avr/avr/include/stdio.h" 3 | |
int size; | |
int len; | |
int (*put)(char, struct __file *); | |
int (*get)(struct __file *); | |
void *udata; | |
}; | |
# 397 "/arduino-1.5.7/hardware/tools/avr/avr/include/stdio.h" 3 | |
extern "C" { | |
extern struct __file *__iob[]; | |
# 417 "/arduino-1.5.7/hardware/tools/avr/avr/include/stdio.h" 3 | |
extern struct __file *fdevopen(int (*__put)(char, struct __file*), int (*__get)(struct __file*)); | |
# 434 "/arduino-1.5.7/hardware/tools/avr/avr/include/stdio.h" 3 | |
extern int fclose(struct __file *__stream); | |
# 608 "/arduino-1.5.7/hardware/tools/avr/avr/include/stdio.h" 3 | |
extern int vfprintf(struct __file *__stream, const char *__fmt, va_list __ap); | |
extern int vfprintf_P(struct __file *__stream, const char *__fmt, va_list __ap); | |
extern int fputc(int __c, struct __file *__stream); | |
extern int putc(int __c, struct __file *__stream); | |
extern int putchar(int __c); | |
# 649 "/arduino-1.5.7/hardware/tools/avr/avr/include/stdio.h" 3 | |
extern int printf(const char *__fmt, ...); | |
extern int printf_P(const char *__fmt, ...); | |
extern int vprintf(const char *__fmt, va_list __ap); | |
extern int sprintf(char *__s, const char *__fmt, ...); | |
extern int sprintf_P(char *__s, const char *__fmt, ...); | |
# 685 "/arduino-1.5.7/hardware/tools/avr/avr/include/stdio.h" 3 | |
extern int snprintf(char *__s, size_t __n, const char *__fmt, ...); | |
extern int snprintf_P(char *__s, size_t __n, const char *__fmt, ...); | |
extern int vsprintf(char *__s, const char *__fmt, va_list ap); | |
extern int vsprintf_P(char *__s, const char *__fmt, va_list ap); | |
# 713 "/arduino-1.5.7/hardware/tools/avr/avr/include/stdio.h" 3 | |
extern int vsnprintf(char *__s, size_t __n, const char *__fmt, va_list ap); | |
extern int vsnprintf_P(char *__s, size_t __n, const char *__fmt, va_list ap); | |
extern int fprintf(struct __file *__stream, const char *__fmt, ...); | |
extern int fprintf_P(struct __file *__stream, const char *__fmt, ...); | |
extern int fputs(const char *__str, struct __file *__stream); | |
extern int fputs_P(const char *__str, struct __file *__stream); | |
extern int puts(const char *__str); | |
extern int puts_P(const char *__str); | |
# 762 "/arduino-1.5.7/hardware/tools/avr/avr/include/stdio.h" 3 | |
extern size_t fwrite(const void *__ptr, size_t __size, size_t __nmemb, | |
struct __file *__stream); | |
extern int fgetc(struct __file *__stream); | |
extern int getc(struct __file *__stream); | |
extern int getchar(void); | |
# 810 "/arduino-1.5.7/hardware/tools/avr/avr/include/stdio.h" 3 | |
extern int ungetc(int __c, struct __file *__stream); | |
# 822 "/arduino-1.5.7/hardware/tools/avr/avr/include/stdio.h" 3 | |
extern char *fgets(char *__str, int __size, struct __file *__stream); | |
extern char *gets(char *__str); | |
# 840 "/arduino-1.5.7/hardware/tools/avr/avr/include/stdio.h" 3 | |
extern size_t fread(void *__ptr, size_t __size, size_t __nmemb, | |
struct __file *__stream); | |
extern void clearerr(struct __file *__stream); | |
# 857 "/arduino-1.5.7/hardware/tools/avr/avr/include/stdio.h" 3 | |
extern int feof(struct __file *__stream); | |
# 868 "/arduino-1.5.7/hardware/tools/avr/avr/include/stdio.h" 3 | |
extern int ferror(struct __file *__stream); | |
extern int vfscanf(struct __file *__stream, const char *__fmt, va_list __ap); | |
extern int vfscanf_P(struct __file *__stream, const char *__fmt, va_list __ap); | |
extern int fscanf(struct __file *__stream, const char *__fmt, ...); | |
extern int fscanf_P(struct __file *__stream, const char *__fmt, ...); | |
extern int scanf(const char *__fmt, ...); | |
extern int scanf_P(const char *__fmt, ...); | |
extern int vscanf(const char *__fmt, va_list __ap); | |
extern int sscanf(const char *__buf, const char *__fmt, ...); | |
extern int sscanf_P(const char *__buf, const char *__fmt, ...); | |
# 938 "/arduino-1.5.7/hardware/tools/avr/avr/include/stdio.h" 3 | |
static __inline__ int fflush(struct __file *stream __attribute__((unused))) | |
{ | |
return 0; | |
} | |
} | |
# 25 "C:\\Documents and Settings\\STEFANOD\\Desktop\\TMP\\clock\\arduino-1.5.7\\hardware\\arduino\\avr\\cores\\arduino/Print.h" 2 | |
# 1 "C:\\Documents and Settings\\STEFANOD\\Desktop\\TMP\\clock\\arduino-1.5.7\\hardware\\arduino\\avr\\cores\\arduino/Printable.h" 1 | |
# 23 "C:\\Documents and Settings\\STEFANOD\\Desktop\\TMP\\clock\\arduino-1.5.7\\hardware\\arduino\\avr\\cores\\arduino/Printable.h" | |
# 1 "C:\\Documents and Settings\\STEFANOD\\Desktop\\TMP\\clock\\arduino-1.5.7\\hardware\\arduino\\avr\\cores\\arduino/new.h" 1 | |
# 10 "C:\\Documents and Settings\\STEFANOD\\Desktop\\TMP\\clock\\arduino-1.5.7\\hardware\\arduino\\avr\\cores\\arduino/new.h" | |
void * operator new(size_t size); | |
void * operator new[](size_t size); | |
void operator delete(void * ptr); | |
void operator delete[](void * ptr); | |
__extension__ typedef int __guard __attribute__((mode (__DI__))); | |
extern "C" int __cxa_guard_acquire(__guard *); | |
extern "C" void __cxa_guard_release (__guard *); | |
extern "C" void __cxa_guard_abort (__guard *); | |
extern "C" void __cxa_pure_virtual(void); | |
# 24 "C:\\Documents and Settings\\STEFANOD\\Desktop\\TMP\\clock\\arduino-1.5.7\\hardware\\arduino\\avr\\cores\\arduino/Printable.h" 2 | |
class Print; | |
class Printable | |
{ | |
public: | |
virtual size_t printTo(Print& p) const = 0; | |
}; | |
# 28 "C:\\Documents and Settings\\STEFANOD\\Desktop\\TMP\\clock\\arduino-1.5.7\\hardware\\arduino\\avr\\cores\\arduino/Print.h" 2 | |
class Print | |
{ | |
private: | |
int write_error; | |
size_t printNumber(unsigned long, uint8_t); | |
size_t printFloat(double, uint8_t); | |
protected: | |
void setWriteError(int err = 1) { write_error = err; } | |
public: | |
Print() : write_error(0) {} | |
int getWriteError() { return write_error; } | |
void clearWriteError() { setWriteError(0); } | |
virtual size_t write(uint8_t) = 0; | |
size_t write(const char *str) { | |
if (str == __null) return 0; | |
return write((const uint8_t *)str, strlen(str)); | |
} | |
virtual size_t write(const uint8_t *buffer, size_t size); | |
size_t write(const char *buffer, size_t size) { | |
return write((const uint8_t *)buffer, size); | |
} | |
size_t print(const __FlashStringHelper *); | |
size_t print(const String &); | |
size_t print(const char[]); | |
size_t print(char); | |
size_t print(unsigned char, int = 10); | |
size_t print(int, int = 10); | |
size_t print(unsigned int, int = 10); | |
size_t print(long, int = 10); | |
size_t print(unsigned long, int = 10); | |
size_t print(double, int = 2); | |
size_t print(const Printable&); | |
size_t println(const __FlashStringHelper *); | |
size_t println(const String &s); | |
size_t println(const char[]); | |
size_t println(char); | |
size_t println(unsigned char, int = 10); | |
size_t println(int, int = 10); | |
size_t println(unsigned int, int = 10); | |
size_t println(long, int = 10); | |
size_t println(unsigned long, int = 10); | |
size_t println(double, int = 2); | |
size_t println(const Printable&); | |
size_t println(void); | |
}; | |
# 27 "C:\\Documents and Settings\\STEFANOD\\Desktop\\TMP\\clock\\arduino-1.5.7\\hardware\\arduino\\avr\\cores\\arduino/Stream.h" 2 | |
# 38 "C:\\Documents and Settings\\STEFANOD\\Desktop\\TMP\\clock\\arduino-1.5.7\\hardware\\arduino\\avr\\cores\\arduino/Stream.h" | |
class Stream : public Print | |
{ | |
protected: | |
unsigned long _timeout; | |
unsigned long _startMillis; | |
int timedRead(); | |
int timedPeek(); | |
int peekNextDigit(); | |
public: | |
virtual int available() = 0; | |
virtual int read() = 0; | |
virtual int peek() = 0; | |
virtual void flush() = 0; | |
Stream() {_timeout=1000;} | |
void setTimeout(unsigned long timeout); | |
bool find(char *target); | |
bool find(uint8_t *target) { return find ((char *)target); } | |
bool find(char *target, size_t length); | |
bool find(uint8_t *target, size_t length) { return find ((char *)target, length); } | |
bool findUntil(char *target, char *terminator); | |
bool findUntil(uint8_t *target, char *terminator) { return findUntil((char *)target, terminator); } | |
bool findUntil(char *target, size_t targetLen, char *terminate, size_t termLen); | |
bool findUntil(uint8_t *target, size_t targetLen, char *terminate, size_t termLen) {return findUntil((char *)target, targetLen, terminate, termLen); } | |
long parseInt(); | |
float parseFloat(); | |
size_t readBytes( char *buffer, size_t length); | |
size_t readBytes( uint8_t *buffer, size_t length) { return readBytes((char *)buffer, length); } | |
size_t readBytesUntil( char terminator, char *buffer, size_t length); | |
size_t readBytesUntil( char terminator, uint8_t *buffer, size_t length) { return readBytesUntil(terminator, (char *)buffer, length); } | |
String readString(); | |
String readStringUntil(char terminator); | |
protected: | |
long parseInt(char skipChar); | |
float parseFloat(char skipChar); | |
}; | |
# 30 "C:\\Documents and Settings\\STEFANOD\\Desktop\\TMP\\clock\\arduino-1.5.7\\hardware\\arduino\\avr\\cores\\arduino/HardwareSerial.h" 2 | |
# 47 "C:\\Documents and Settings\\STEFANOD\\Desktop\\TMP\\clock\\arduino-1.5.7\\hardware\\arduino\\avr\\cores\\arduino/HardwareSerial.h" | |
typedef uint8_t tx_buffer_index_t; | |
typedef uint8_t rx_buffer_index_t; | |
# 81 "C:\\Documents and Settings\\STEFANOD\\Desktop\\TMP\\clock\\arduino-1.5.7\\hardware\\arduino\\avr\\cores\\arduino/HardwareSerial.h" | |
class HardwareSerial : public Stream | |
{ | |
protected: | |
volatile uint8_t * const _ubrrh; | |
volatile uint8_t * const _ubrrl; | |
volatile uint8_t * const _ucsra; | |
volatile uint8_t * const _ucsrb; | |
volatile uint8_t * const _ucsrc; | |
volatile uint8_t * const _udr; | |
bool _written; | |
volatile rx_buffer_index_t _rx_buffer_head; | |
volatile rx_buffer_index_t _rx_buffer_tail; | |
volatile tx_buffer_index_t _tx_buffer_head; | |
volatile tx_buffer_index_t _tx_buffer_tail; | |
unsigned char _rx_buffer[64]; | |
unsigned char _tx_buffer[64]; | |
public: | |
inline HardwareSerial( | |
volatile uint8_t *ubrrh, volatile uint8_t *ubrrl, | |
volatile uint8_t *ucsra, volatile uint8_t *ucsrb, | |
volatile uint8_t *ucsrc, volatile uint8_t *udr); | |
void begin(unsigned long baud) { begin(baud, 0x06); } | |
void begin(unsigned long, uint8_t); | |
void end(); | |
virtual int available(void); | |
virtual int peek(void); | |
virtual int read(void); | |
virtual void flush(void); | |
virtual size_t write(uint8_t); | |
inline size_t write(unsigned long n) { return write((uint8_t)n); } | |
inline size_t write(long n) { return write((uint8_t)n); } | |
inline size_t write(unsigned int n) { return write((uint8_t)n); } | |
inline size_t write(int n) { return write((uint8_t)n); } | |
using Print::write; | |
operator bool() { return true; } | |
inline void _rx_complete_irq(void); | |
void _tx_udr_empty_irq(void); | |
}; | |
extern HardwareSerial Serial; | |
extern HardwareSerial Serial1; | |
extern HardwareSerial Serial2; | |
extern HardwareSerial Serial3; | |
extern void serialEventRun(void) __attribute__((weak)); | |
# 222 "C:\\Documents and Settings\\STEFANOD\\Desktop\\TMP\\clock\\arduino-1.5.7\\hardware\\arduino\\avr\\cores\\arduino/Arduino.h" 2 | |
# 1 "C:\\Documents and Settings\\STEFANOD\\Desktop\\TMP\\clock\\arduino-1.5.7\\hardware\\arduino\\avr\\cores\\arduino/USBAPI.h" 1 | |
# 223 "C:\\Documents and Settings\\STEFANOD\\Desktop\\TMP\\clock\\arduino-1.5.7\\hardware\\arduino\\avr\\cores\\arduino/Arduino.h" 2 | |
uint16_t makeWord(uint16_t w); | |
uint16_t makeWord(byte h, byte l); | |
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L); | |
void tone(uint8_t _pin, unsigned int frequency, unsigned long duration = 0); | |
void noTone(uint8_t _pin); | |
long random(long); | |
long random(long, long); | |
void randomSeed(unsigned int); | |
long map(long, long, long, long, long); | |
# 1 "C:\\Documents and Settings\\STEFANOD\\Desktop\\TMP\\clock\\arduino-1.5.7\\hardware\\arduino\\avr\\variants\\mega/pins_arduino.h" 1 | |
# 35 "C:\\Documents and Settings\\STEFANOD\\Desktop\\TMP\\clock\\arduino-1.5.7\\hardware\\arduino\\avr\\variants\\mega/pins_arduino.h" | |
static const uint8_t SS = 53; | |
static const uint8_t MOSI = 51; | |
static const uint8_t MISO = 50; | |
static const uint8_t SCK = 52; | |
static const uint8_t SDA = 20; | |
static const uint8_t SCL = 21; | |
static const uint8_t A0 = 54; | |
static const uint8_t A1 = 55; | |
static const uint8_t A2 = 56; | |
static const uint8_t A3 = 57; | |
static const uint8_t A4 = 58; | |
static const uint8_t A5 = 59; | |
static const uint8_t A6 = 60; | |
static const uint8_t A7 = 61; | |
static const uint8_t A8 = 62; | |
static const uint8_t A9 = 63; | |
static const uint8_t A10 = 64; | |
static const uint8_t A11 = 65; | |
static const uint8_t A12 = 66; | |
static const uint8_t A13 = 67; | |
static const uint8_t A14 = 68; | |
static const uint8_t A15 = 69; | |
# 246 "C:\\Documents and Settings\\STEFANOD\\Desktop\\TMP\\clock\\arduino-1.5.7\\hardware\\arduino\\avr\\cores\\arduino/Arduino.h" 2 | |
# 24 "C:\\Documents and Settings\\STEFANOD\\Documenti\\Arduino\\libraries\\dcf77_library/dcf77.h" 2 | |
namespace BCD { | |
typedef union { | |
struct { | |
uint8_t lo:4; | |
uint8_t hi:4; | |
} digit; | |
struct { | |
uint8_t b0:1; | |
uint8_t b1:1; | |
uint8_t b2:1; | |
uint8_t b3:1; | |
uint8_t b4:1; | |
uint8_t b5:1; | |
uint8_t b6:1; | |
uint8_t b7:1; | |
} bit; | |
uint8_t val; | |
} bcd_t; | |
void increment(bcd_t &value); | |
bcd_t int_to_bcd(const uint8_t value); | |
uint8_t bcd_to_int(const bcd_t value); | |
} | |
namespace DCF77_Clock { | |
typedef struct { | |
BCD::bcd_t year; | |
BCD::bcd_t month; | |
BCD::bcd_t day; | |
BCD::bcd_t weekday; | |
BCD::bcd_t hour; | |
BCD::bcd_t minute; | |
BCD::bcd_t second; | |
bool uses_summertime; | |
bool timezone_change_scheduled; | |
bool leap_second_scheduled; | |
} time_t; | |
typedef void (*output_handler_t)(const time_t &decoded_time); | |
typedef uint8_t (*input_provider_t)(void); | |
void setup(); | |
void setup(const input_provider_t input_provider, const output_handler_t output_handler); | |
void set_input_provider(const input_provider_t); | |
void set_output_handler(const output_handler_t output_handler); | |
void get_current_time(time_t &now); | |
void read_current_time(time_t &now); | |
void auto_persist(); | |
void print(time_t time); | |
void debug(); | |
uint8_t get_overall_quality_factor(); | |
typedef enum { | |
useless = 0, | |
dirty = 1, | |
free = 2, | |
unlocked = 3, | |
locked = 4, | |
synced = 5 | |
} clock_state_t; | |
uint8_t get_clock_state(); | |
uint8_t get_prediction_match(); | |
} | |
namespace DCF77 { | |
typedef enum { | |
long_tick = 3, | |
short_tick = 2, | |
undefined = 1, | |
sync_mark = 0 | |
} tick_t; | |
typedef struct { | |
uint8_t byte_0; | |
uint8_t byte_1; | |
uint8_t byte_2; | |
uint8_t byte_3; | |
uint8_t byte_4; | |
uint8_t byte_5; | |
} serialized_clock_stream; | |
typedef struct { | |
BCD::bcd_t year; | |
BCD::bcd_t month; | |
BCD::bcd_t day; | |
BCD::bcd_t weekday; | |
BCD::bcd_t hour; | |
BCD::bcd_t minute; | |
uint8_t second; | |
bool uses_summertime : 1; | |
bool abnormal_transmitter_operation : 1; | |
bool timezone_change_scheduled : 1; | |
bool leap_second_scheduled : 1; | |
bool undefined_minute_output : 1; | |
bool undefined_uses_summertime_output : 1; | |
bool undefined_abnormal_transmitter_operation_output: 1; | |
bool undefined_timezone_change_scheduled_output : 1; | |
} time_data_t; | |
typedef void (*output_handler_t)(const DCF77::time_data_t &decoded_time); | |
typedef enum { | |
useless = 0, | |
dirty = 1, | |
free = 2, | |
unlocked = 3, | |
locked = 4, | |
synced = 5 | |
} clock_state_t; | |
} | |
namespace DCF77_1_Khz_Generator { | |
void setup(const DCF77_Clock::input_provider_t input_provider); | |
uint8_t zero_provider(); | |
void adjust(const int16_t pp16m); | |
int16_t read_adjustment(); | |
void isr_handler(); | |
} | |
namespace DCF77_Frequency_Control { | |
const uint16_t tau_min_minutes = 334; | |
const uint16_t tau_max_minutes = 5334; | |
const int16_t max_total_adjust = 1600; | |
void restart_measurement(); | |
void debug(); | |
bool increase_tau(); | |
bool decrease_tau(); | |
void adjust(); | |
void process_1_Hz_tick(const DCF77::time_data_t &decoded_time); | |
void process_1_kHz_tick(); | |
void qualify_calibration(); | |
void unqualify_calibration(); | |
typedef struct { | |
bool qualified : 1; | |
bool running : 1; | |
} calibration_state_t; | |
calibration_state_t get_calibration_state(); | |
int16_t get_current_deviation(); | |
void setup(); | |
const uint16_t eeprom_base = 0x00; | |
void persist_to_eeprom(const int8_t adjust_steps, const int16_t adjust); | |
void read_from_eeprom(int8_t &adjust_steps, int16_t &adjust); | |
void read_from_eeprom(int8_t &adjust_steps, int16_t &adjust, uint32_t &tau); | |
void auto_persist(); | |
int8_t get_confirmed_precision(); | |
} | |
namespace Debug { | |
void debug_helper(char data); | |
void bcddigit(uint8_t data); | |
void bcddigits(uint8_t data); | |
} | |
namespace Hamming { | |
typedef struct { | |
uint8_t lock_max; | |
uint8_t noise_max; | |
} lock_quality_t; | |
} | |
namespace DCF77_Encoder { | |
void reset(DCF77::time_data_t &now); | |
void get_serialized_clock_stream(const DCF77::time_data_t &now, DCF77::serialized_clock_stream &data); | |
uint8_t weekday(const DCF77::time_data_t &now); | |
BCD::bcd_t bcd_weekday(const DCF77::time_data_t &now); | |
DCF77::tick_t get_current_signal(const DCF77::time_data_t &now); | |
void advance_second(DCF77::time_data_t &now); | |
void advance_minute(DCF77::time_data_t &now); | |
void autoset_weekday(DCF77::time_data_t &now); | |
void autoset_control_bits(DCF77::time_data_t &now); | |
bool verify_leap_second_scheduled(const DCF77::time_data_t &now); | |
void debug(const DCF77::time_data_t &clock); | |
void debug(const DCF77::time_data_t &clock, const uint16_t cycles); | |
# 360 "C:\\Documents and Settings\\STEFANOD\\Documenti\\Arduino\\libraries\\dcf77_library/dcf77.h" | |
} | |
namespace DCF77_Naive_Bitstream_Decoder { | |
void set_bit(const uint8_t second, const uint8_t value, DCF77::time_data_t &now); | |
} | |
namespace DCF77_Flag_Decoder { | |
void setup(); | |
void process_tick(const uint8_t current_second, const uint8_t tick_value); | |
void reset_after_previous_hour(); | |
void reset_before_new_day(); | |
bool get_uses_summertime(); | |
bool get_abnormal_transmitter_operation(); | |
bool get_timezone_change_scheduled(); | |
bool get_leap_second_scheduled(); | |
void debug(); | |
} | |
namespace DCF77_Decade_Decoder { | |
void setup(); | |
void process_tick(const uint8_t current_second, const uint8_t tick_value); | |
void advance_decade(); | |
BCD::bcd_t get_decade(); | |
void get_quality(Hamming::lock_quality_t &lock_quality); | |
uint8_t get_quality_factor(); | |
void debug(); | |
} | |
namespace DCF77_Year_Decoder { | |
void setup(); | |
void process_tick(const uint8_t current_second, const uint8_t tick_value); | |
void advance_year(); | |
BCD::bcd_t get_year(); | |
void get_quality(Hamming::lock_quality_t &lock_quality); | |
uint8_t get_quality_factor(); | |
void debug(); | |
} | |
namespace DCF77_Month_Decoder { | |
void setup(); | |
void process_tick(const uint8_t current_second, const uint8_t tick_value); | |
void advance_month(); | |
BCD::bcd_t get_month(); | |
void get_quality(Hamming::lock_quality_t &lock_quality); | |
uint8_t get_quality_factor(); | |
void debug(); | |
} | |
namespace DCF77_Day_Decoder { | |
void setup(); | |
void process_tick(const uint8_t current_second, const uint8_t tick_value); | |
void advance_day(); | |
BCD::bcd_t get_day(); | |
void get_quality(Hamming::lock_quality_t &lock_quality); | |
uint8_t get_quality_factor(); | |
void debug(); | |
} | |
namespace DCF77_Weekday_Decoder { | |
void setup(); | |
void process_tick(const uint8_t current_second, const uint8_t tick_value); | |
void advance_weekday(); | |
BCD::bcd_t get_weekday(); | |
void get_quality(Hamming::lock_quality_t &lock_quality); | |
uint8_t get_quality_factor(); | |
void debug(); | |
} | |
namespace DCF77_Hour_Decoder { | |
void setup(); | |
void process_tick(const uint8_t current_second, const uint8_t tick_value); | |
void advance_hour(); | |
BCD::bcd_t get_hour(); | |
void get_quality(Hamming::lock_quality_t &lock_quality); | |
uint8_t get_quality_factor(); | |
void debug(); | |
} | |
namespace DCF77_Minute_Decoder { | |
void setup(); | |
void process_tick(const uint8_t current_second, const uint8_t tick_value); | |
void advance_minute(); | |
BCD::bcd_t get_minute(); | |
void get_quality(Hamming::lock_quality_t &lock_quality); | |
uint8_t get_quality_factor(); | |
void debug(); | |
} | |
namespace DCF77_Second_Decoder { | |
void setup(); | |
void set_convolution_time(const DCF77::time_data_t &now); | |
void process_single_tick_data(const DCF77::tick_t tick_data); | |
uint8_t get_second(); | |
void get_quality(Hamming::lock_quality_t &lock_quality); | |
uint8_t get_quality_factor(); | |
uint8_t get_prediction_match(); | |
void debug(); | |
} | |
namespace DCF77_Local_Clock { | |
typedef enum { | |
useless = 0, | |
dirty = 1, | |
free = 2, | |
unlocked = 3, | |
locked = 4, | |
synced = 5 | |
} clock_state_t; | |
void setup(); | |
void set_has_tuned_clock(); | |
void process_1_Hz_tick(const DCF77::time_data_t &decoded_time); | |
void process_1_kHz_tick(); | |
void debug(); | |
clock_state_t get_state(); | |
void get_current_time(DCF77::time_data_t &now); | |
void read_current_time(DCF77::time_data_t &now); | |
} | |
namespace DCF77_Clock_Controller { | |
void setup(); | |
void process_1_kHz_tick_data(const uint8_t sampled_data); | |
void process_single_tick_data(const DCF77::tick_t tick_data); | |
void flush(const DCF77::time_data_t &decoded_time); | |
void set_output_handler(const DCF77_Clock::output_handler_t output_handler); | |
void auto_persist(); | |
void on_tuned_clock(); | |
typedef Hamming::lock_quality_t lock_quality_t; | |
typedef struct { | |
struct { | |
uint32_t lock_max; | |
uint32_t noise_max; | |
} phase; | |
DCF77::clock_state_t clock_state; | |
uint8_t prediction_match; | |
lock_quality_t second; | |
lock_quality_t minute; | |
lock_quality_t hour; | |
lock_quality_t weekday; | |
lock_quality_t day; | |
lock_quality_t month; | |
lock_quality_t year; | |
uint8_t uses_summertime_quality; | |
uint8_t timezone_change_scheduled_quality; | |
uint8_t leap_second_scheduled_quality; | |
} clock_quality_t; | |
void get_quality(clock_quality_t &clock_quality); | |
typedef struct { | |
uint8_t phase; | |
uint8_t second; | |
uint8_t minute; | |
uint8_t hour; | |
uint8_t weekday; | |
uint8_t day; | |
uint8_t month; | |
uint8_t year; | |
} clock_quality_factor_t; | |
void get_quality_factor(clock_quality_factor_t &clock_quality_factor); | |
uint8_t get_overall_quality_factor(); | |
uint8_t get_clock_state(); | |
uint8_t get_prediction_match(); | |
void phase_lost_event_handler(); | |
void sync_lost_event_handler(); | |
void sync_achieved_event_handler(); | |
void get_current_time(DCF77::time_data_t &now); | |
void read_current_time(DCF77::time_data_t &now); | |
void debug(); | |
} | |
namespace DCF77_Demodulator { | |
void setup(); | |
void set_has_tuned_clock(); | |
void detector(const uint8_t sampled_data); | |
void get_quality(uint32_t &lock_max, uint32_t &noise_max); | |
void get_noise_indicator(uint32_t &noise_indicator); | |
uint8_t get_quality_factor(); | |
void debug(); | |
void debug_verbose(); | |
} | |
# 20 "C:\\Documents and Settings\\STEFANOD\\Documenti\\Arduino\\libraries\\dcf77_library\\dcf77.cpp" 2 | |
# 1 "/arduino-1.5.7/hardware/tools/avr/avr/include/avr/eeprom.h" 1 3 | |
# 560 "/arduino-1.5.7/hardware/tools/avr/avr/include/avr/eeprom.h" 3 | |
# 1 "/arduino-1.5.7/hardware/tools/avr/lib/gcc/avr/4.8.1/include/stddef.h" 1 3 4 | |
# 147 "/arduino-1.5.7/hardware/tools/avr/lib/gcc/avr/4.8.1/include/stddef.h" 3 4 | |
typedef int ptrdiff_t; | |
# 561 "/arduino-1.5.7/hardware/tools/avr/avr/include/avr/eeprom.h" 2 3 | |
# 602 "/arduino-1.5.7/hardware/tools/avr/avr/include/avr/eeprom.h" 3 | |
extern "C" { | |
# 647 "/arduino-1.5.7/hardware/tools/avr/avr/include/avr/eeprom.h" 3 | |
uint8_t __eerd_byte_m2560 (const uint8_t *__p) __attribute__((__pure__)); | |
uint16_t __eerd_word_m2560 (const uint16_t *__p) __attribute__((__pure__)); | |
uint32_t __eerd_dword_m2560 (const uint32_t *__p) __attribute__((__pure__)); | |
float __eerd_float_m2560 (const float *__p) __attribute__((__pure__)); | |
void __eerd_block_m2560 (void *__dst, const void *__src, size_t __n); | |
void __eewr_byte_m2560 (uint8_t *__p, uint8_t __value); | |
void __eewr_word_m2560 (uint16_t *__p, uint16_t __value); | |
void __eewr_dword_m2560 (uint32_t *__p, uint32_t __value); | |
void __eewr_float_m2560 (float *__p, float __value); | |
void __eewr_block_m2560 (const void *__src, void *__dst, size_t __n); | |
void __eeupd_byte_m2560 (uint8_t *__p, uint8_t __value); | |
void __eeupd_word_m2560 (uint16_t *__p, uint16_t __value); | |
void __eeupd_dword_m2560 (uint32_t *__p, uint32_t __value); | |
void __eeupd_float_m2560 (float *__p, float __value); | |
void __eeupd_block_m2560 (const void *__src, void *__dst, size_t __n); | |
# 751 "/arduino-1.5.7/hardware/tools/avr/avr/include/avr/eeprom.h" 3 | |
} | |
# 21 "C:\\Documents and Settings\\STEFANOD\\Documenti\\Arduino\\libraries\\dcf77_library\\dcf77.cpp" 2 | |
namespace Debug { | |
void debug_helper(char data) { Serial.print(data == 0? 'S': data == 1? '?': data - 2 + '0', 0); } | |
void bcddigit(uint8_t data) { | |
if (data <= 0x09) { | |
Serial.print(data, 16); | |
} else { | |
Serial.print('?'); | |
} | |
} | |
void bcddigits(uint8_t data) { | |
bcddigit(data >> 4); | |
bcddigit(data & 0xf); | |
} | |
} | |
namespace BCD { | |
void print(const bcd_t value) { | |
Serial.print(value.val >> 4 & 0xF, 16); | |
Serial.print(value.val >> 0 & 0xF, 16); | |
} | |
void increment(bcd_t &value) { | |
if (value.digit.lo < 9) { | |
++value.digit.lo; | |
} else { | |
value.digit.lo = 0; | |
if (value.digit.hi < 9) { | |
++value.digit.hi; | |
} else { | |
value.digit.hi = 0; | |
} | |
} | |
} | |
bcd_t int_to_bcd(const uint8_t value) { | |
const uint8_t hi = value / 10; | |
bcd_t result; | |
result.digit.hi = hi; | |
result.digit.lo = value-10*hi; | |
return result; | |
} | |
uint8_t bcd_to_int(const bcd_t value) { | |
return value.digit.lo + 10*value.digit.hi; | |
} | |
} | |
namespace Arithmetic_Tools { | |
template <uint8_t N> inline void bounded_increment(uint8_t &value) __attribute__((always_inline)); | |
template <uint8_t N> | |
void bounded_increment(uint8_t &value) { | |
if (value >= 255 - N) { value = 255; } else { value += N; } | |
} | |
template <uint8_t N> inline void bounded_decrement(uint8_t &value) __attribute__((always_inline)); | |
template <uint8_t N> | |
void bounded_decrement(uint8_t &value) { | |
if (value <= N) { value = 0; } else { value -= N; } | |
} | |
inline void bounded_add(uint8_t &value, const uint8_t amount) __attribute__((always_inline)); | |
void bounded_add(uint8_t &value, const uint8_t amount) { | |
if (value >= 255-amount) { value = 255; } else { value += amount; } | |
} | |
inline void bounded_sub(uint8_t &value, const uint8_t amount) __attribute__((always_inline)); | |
void bounded_sub(uint8_t &value, const uint8_t amount) { | |
if (value <= amount) { value = 0; } else { value -= amount; } | |
} | |
inline uint8_t bit_count(const uint8_t value) __attribute__((always_inline)); | |
uint8_t bit_count(const uint8_t value) { | |
const uint8_t tmp1 = (value & 0b01010101) + ((value>>1) & 0b01010101); | |
const uint8_t tmp2 = (tmp1 & 0b00110011) + ((tmp1>>2) & 0b00110011); | |
return (tmp2 & 0x0f) + (tmp2>>4); | |
} | |
inline uint8_t parity(const uint8_t value) __attribute__((always_inline)); | |
uint8_t parity(const uint8_t value) { | |
uint8_t tmp = value; | |
tmp = (tmp & 0xf) ^ (tmp >> 4); | |
tmp = (tmp & 0x3) ^ (tmp >> 2); | |
tmp = (tmp & 0x1) ^ (tmp >> 1); | |
return tmp; | |
} | |
void minimize(uint8_t &minimum, const uint8_t value) { | |
if (value < minimum) { | |
minimum = value; | |
} | |
} | |
void maximize(uint8_t &maximum, const uint8_t value) { | |
if (value > maximum) { | |
maximum = value; | |
} | |
} | |
uint8_t set_bit(const uint8_t data, const uint8_t number, const uint8_t value) { | |
return value? data|(1<<number): data&~(1<<number); | |
} | |
} | |
namespace Hamming { | |
template <uint8_t significant_bits> | |
void score (uint8_t &bin, const BCD::bcd_t input, const BCD::bcd_t candidate) { | |
using namespace Arithmetic_Tools; | |
const uint8_t the_score = significant_bits - bit_count(input.val ^ candidate.val); | |
bounded_add(bin, the_score); | |
} | |
template <typename bins_t> | |
void advance_tick(bins_t &bins) { | |
const uint8_t number_of_bins = sizeof(bins.data) / sizeof(bins.data[0]); | |
if (bins.tick < number_of_bins - 1) { | |
++bins.tick; | |
} else { | |
bins.tick = 0; | |
} | |
} | |
template <typename bins_type, uint8_t significant_bits, bool with_parity> | |
void hamming_binning(bins_type &bins, const BCD::bcd_t input) { | |
using namespace Arithmetic_Tools; | |
using namespace BCD; | |
const uint8_t number_of_bins = sizeof(bins.data) / sizeof(bins.data[0]); | |
if (bins.max > 255-significant_bits) { | |
for (uint8_t bin_index = 0; bin_index <number_of_bins; ++bin_index) { | |
bounded_decrement<significant_bits>(bins.data[bin_index]); | |
} | |
bins.max -= significant_bits; | |
bounded_decrement<significant_bits>(bins.noise_max); | |
} | |
const uint8_t offset = number_of_bins-1-bins.tick; | |
uint8_t bin_index = offset; | |
bcd_t candidate; | |
candidate.val = (with_parity || number_of_bins == 10)? 0x00: 0x01; | |
for (uint8_t pass=0; pass < number_of_bins; ++pass) { | |
if (with_parity) { | |
candidate.bit.b7 = parity(candidate.val); | |
score<significant_bits>(bins.data[bin_index], input, candidate); | |
candidate.bit.b7 = 0; | |
} else { | |
score<significant_bits>(bins.data[bin_index], input, candidate); | |
} | |
bin_index = bin_index < number_of_bins-1? bin_index+1: 0; | |
increment(candidate); | |
} | |
} | |
template <typename bins_t> | |
void compute_max_index(bins_t &bins) { | |
const uint8_t number_of_bins = sizeof(bins.data) / sizeof(bins.data[0]); | |
bins.noise_max = 0; | |
bins.max = 0; | |
bins.max_index = 255; | |
for (uint8_t index = 0; index < number_of_bins; ++index) { | |
const uint8_t bin_data = bins.data[index]; | |
if (bin_data >= bins.max) { | |
bins.noise_max = bins.max; | |
bins.max = bin_data; | |
bins.max_index = index; | |
} else if (bin_data > bins.noise_max) { | |
bins.noise_max = bin_data; | |
} | |
} | |
} | |
template <typename bins_t> | |
void setup(bins_t &bins) { | |
const uint8_t number_of_bins = sizeof(bins.data) / sizeof(bins.data[0]); | |
for (uint8_t index = 0; index < number_of_bins; ++index) { | |
bins.data[index] = 0; | |
} | |
bins.tick = 0; | |
bins.max = 0; | |
bins.max_index = 255; | |
bins.noise_max = 0; | |
} | |
template <typename bins_t> | |
BCD::bcd_t get_time_value(const bins_t &bins) { | |
const uint8_t threshold = 2; | |
const uint8_t number_of_bins = sizeof(bins.data) / sizeof(bins.data[0]); | |
const uint8_t offset = (number_of_bins == 60 || number_of_bins == 24 || number_of_bins == 10)? 0x00: 0x01; | |
if (bins.max-bins.noise_max >= threshold) { | |
return BCD::int_to_bcd((bins.max_index + bins.tick + 1) % number_of_bins + offset); | |
} else { | |
BCD::bcd_t undefined; | |
undefined.val = 0xff; | |
return undefined; | |
} | |
} | |
template <typename bins_t> | |
void get_quality(const bins_t bins, Hamming::lock_quality_t &lock_quality) { | |
const uint8_t prev_SREG = (*(volatile uint8_t *)((0x3F) + 0x20)); | |
__asm__ __volatile__ ("cli" ::: "memory"); | |
lock_quality.lock_max = bins.max; | |
lock_quality.noise_max = bins.noise_max; | |
(*(volatile uint8_t *)((0x3F) + 0x20)) = prev_SREG; | |
} | |
template <typename bins_t> | |
uint8_t get_quality_factor(const bins_t bins) { | |
const uint8_t prev_SREG = (*(volatile uint8_t *)((0x3F) + 0x20)); | |
__asm__ __volatile__ ("cli" ::: "memory"); | |
uint8_t quality_factor; | |
if (bins.max <= bins.noise_max) { | |
quality_factor = 0; | |
} else { | |
const uint16_t delta = bins.max - bins.noise_max; | |
# 276 "C:\\Documents and Settings\\STEFANOD\\Documenti\\Arduino\\libraries\\dcf77_library\\dcf77.cpp" | |
if (bins.max >= 32-3) { | |
uint16_t max = bins.max; | |
uint8_t log2 = 0; | |
while (max > 0) { | |
max >>= 1; | |
++log2; | |
} | |
log2 -= 1; | |
const uint16_t multiplier = | |
log2 > 12? log2 > 13? log2 > 14? 256/15 | |
: 256/14 | |
: 256/13 | |
: log2 > 8 ? log2 > 10? log2 > 11? 256/12 | |
: 256/11 | |
: log2 > 9? 256/10 | |
: 256/ 9 | |
: log2 > 6? log2 > 7? 256/ 8 | |
: 256/ 7 | |
: log2 > 5? 256/ 6 | |
: 256/ 5; | |
quality_factor = ((uint16_t)delta * multiplier) >> 8; | |
} else if (bins.max >= 16-3) { | |
quality_factor = delta >> 2; | |
} else if (bins.max >= 12-3) { | |
quality_factor = delta >= 11? 3: | |
delta >= 7? 2: | |
delta >= 4? 1: | |
0; | |
} else if (bins.max >= 8-3) { | |
quality_factor = delta >= 6? 2: | |
delta >= 3? 1: | |
0; | |
} else if (bins.max >= 6-3) { | |
quality_factor = delta >= 3? 1: 0; | |
} else { | |
quality_factor = delta >> 1; | |
} | |
} | |
(*(volatile uint8_t *)((0x3F) + 0x20)) = prev_SREG; | |
return quality_factor; | |
} | |
template <typename bins_t> | |
void debug (const bins_t &bins) { | |
const uint8_t number_of_bins = sizeof(bins.data) / sizeof(bins.data[0]); | |
const bool uses_integrals = sizeof(bins.max) == 4; | |
Serial.print(get_time_value(bins).val, 16); | |
Serial.print((reinterpret_cast<const __FlashStringHelper *>((__extension__({static const char __c[] __attribute__((__progmem__)) = (" Tick: "); &__c[0];}))))); | |
Serial.print(bins.tick); | |
Serial.print((reinterpret_cast<const __FlashStringHelper *>((__extension__({static const char __c[] __attribute__((__progmem__)) = (" Quality: "); &__c[0];}))))); | |
Serial.print(bins.max, 10); | |
Serial.print('-'); | |
Serial.print(bins.noise_max, 10); | |
Serial.print((reinterpret_cast<const __FlashStringHelper *>((__extension__({static const char __c[] __attribute__((__progmem__)) = (" Max Index: "); &__c[0];}))))); | |
Serial.print(bins.max_index, 10); | |
Serial.print((reinterpret_cast<const __FlashStringHelper *>((__extension__({static const char __c[] __attribute__((__progmem__)) = (" Quality Factor: "); &__c[0];}))))); | |
Serial.println(get_quality_factor(bins), 10); | |
Serial.print('>'); | |
for (uint8_t index = 0; index < number_of_bins; ++index) { | |
Serial.print( | |
(index == bins.max_index || | |
(!uses_integrals && index == (bins.max_index+1) % number_of_bins) || | |
(uses_integrals && (index == (bins.max_index+10) % number_of_bins || (index == (bins.max_index+20) % number_of_bins)))) | |
? '|': ','); | |
Serial.print(bins.data[index], 16); | |
} | |
Serial.println(); | |
} | |
} | |
namespace DCF77_Encoder { | |
using namespace DCF77; | |
inline uint8_t days_per_month(const DCF77::time_data_t &now) __attribute__((always_inline)); | |
uint8_t days_per_month(const DCF77::time_data_t &now) { | |
switch (now.month.val) { | |
case 0x02: | |
return 28 + ((now.year.val != 0) && ((bcd_to_int(now.year) & 0x03) == 0)? 1: 0); | |
case 0x01: case 0x03: case 0x05: case 0x07: case 0x08: case 0x10: case 0x12: return 31; | |
case 0x04: case 0x06: case 0x09: case 0x11: return 30; | |
default: return 0; | |
} | |
} | |
void reset(DCF77::time_data_t &now) { | |
now.second = 0; | |
now.minute.val = 0x00; | |
now.hour.val = 0x00; | |
now.day.val = 0x01; | |
now.month.val = 0x01; | |
now.year.val = 0x00; | |
now.weekday.val = 0x01; | |
now.uses_summertime = false; | |
now.abnormal_transmitter_operation = false; | |
now.timezone_change_scheduled = false; | |
now.leap_second_scheduled = false; | |
now.undefined_minute_output = false; | |
now.undefined_uses_summertime_output = false; | |
now.undefined_abnormal_transmitter_operation_output = false; | |
now.undefined_timezone_change_scheduled_output = false; | |
} | |
uint8_t weekday(const DCF77::time_data_t &now) { | |
using namespace BCD; | |
if (now.day.val <= 0x31 && now.month.val <= 0x12 && now.year.val <= 0x99) { | |
const uint8_t d = bcd_to_int(now.day); | |
const uint16_t m = now.month.val <= 0x02? now.month.val + 10: | |
bcd_to_int(now.month) - 2; | |
const uint8_t y = bcd_to_int(now.year) - (now.month.val <= 0x02); | |
uint8_t day_mod_7 = d + (26*m - 2)/10 + y + y/4; | |
while (day_mod_7 >= 7) { | |
day_mod_7 -= 7; | |
day_mod_7 = (day_mod_7 >> 3) + (day_mod_7 & 7); | |
} | |
return day_mod_7; | |
} else { | |
return 0xff; | |
} | |
} | |
BCD::bcd_t bcd_weekday(const DCF77::time_data_t &now) { | |
BCD::bcd_t today; | |
today.val = weekday(now); | |
if (today.val == 0) { | |
today.val = 7; | |
} | |
return today; | |
} | |
void autoset_weekday(DCF77::time_data_t &now) { | |
now.weekday = bcd_weekday(now); | |
} | |
void autoset_timezone(DCF77::time_data_t &now) { | |
if (now.month.val < 0x03) { | |
now.uses_summertime = false; | |
} else | |
if (now.month.val == 0x03) { | |
if (now.day.val < 0x25) { | |
now.uses_summertime = false; | |
} else | |
if (uint8_t wd = weekday(now)) { | |
if (now.day.val - wd < 0x25) { | |
now.uses_summertime = false; | |
} else { | |
now.uses_summertime = true; | |
} | |
} else { | |
now.uses_summertime = (now.hour.val > 2); | |
} | |
} else | |
if (now.month.val < 0x10) { | |
now.uses_summertime = true; | |
} else | |
if (now.month.val == 0x10) { | |
if (now.day.val < 0x25) { | |
now.uses_summertime = true; | |
} else | |
if (uint8_t wd = weekday(now)) { | |
if (now.day.val - wd < 0x25) { | |
now.uses_summertime = true; | |
} else { | |
now.uses_summertime = false; | |
} | |
} else { | |
if (now.hour.val == 2) { | |
} else { | |
now.uses_summertime = (now.hour.val < 2); | |
} | |
} | |
} else { | |
now.uses_summertime = false; | |
} | |
} | |
void autoset_timezone_change_scheduled(DCF77::time_data_t &now) { | |
if (now.day.val < 0x25 || weekday(now) != 0) { | |
now.timezone_change_scheduled = false; | |
} else { | |
if (now.month.val == 0x03) { | |
if (now.uses_summertime) { | |
now.timezone_change_scheduled = (now.hour.val == 0x03 && now.minute.val == 0x00); | |
} else { | |
now.timezone_change_scheduled = (now.hour.val == 0x01 && now.minute.val != 0x00); | |
} | |
} else if (now.month.val == 0x10) { | |
if (now.uses_summertime) { | |
now.timezone_change_scheduled = (now.hour.val == 0x02 && now.minute.val != 0x00); | |
} else { | |
now.timezone_change_scheduled = (now.hour.val == 0x02 && now.minute.val == 0x00); | |
} | |
} else if (now.month.val <= 0x12) { | |
now.timezone_change_scheduled = false; | |
} | |
} | |
} | |
bool verify_leap_second_scheduled(const DCF77::time_data_t &now) { | |
bool leap_second_scheduled = now.leap_second_scheduled && now.day.val == 0x01; | |
if (now.month.val == 0x01) { | |
leap_second_scheduled &= ((now.hour.val == 0x00 && now.minute.val != 0x00) || | |
(now.hour.val == 0x01 && now.minute.val == 0x00)); | |
} else if (now.month.val == 0x07 || now.month.val == 0x04 || now.month.val == 0x10) { | |
leap_second_scheduled &= ((now.hour.val == 0x01 && now.minute.val != 0x00) || | |
(now.hour.val == 0x02 && now.minute.val == 0x00)); | |
} else { | |
leap_second_scheduled = false; | |
} | |
return leap_second_scheduled; | |
} | |
void autoset_control_bits(DCF77::time_data_t &now) { | |
autoset_weekday(now); | |
autoset_timezone(now); | |
autoset_timezone_change_scheduled(now); | |
now.leap_second_scheduled = verify_leap_second_scheduled(now); | |
} | |
void advance_second(DCF77::time_data_t &now) { | |
if (now.second < 59) { | |
++now.second; | |
if (now.second == 15) { | |
autoset_control_bits(now); | |
} | |
} else if (now.leap_second_scheduled && now.second == 59 && now.minute.val == 0x00) { | |
now.second = 60; | |
now.leap_second_scheduled = false; | |
} else if (now.second == 59 || now.second == 60) { | |
now.second = 0; | |
advance_minute(now); | |
} | |
} | |
void advance_minute(DCF77::time_data_t &now) { | |
if (now.minute.val < 0x59) { | |
increment(now.minute); | |
} else if (now.minute.val == 0x59) { | |
now.minute.val = 0x00; | |
if (now.timezone_change_scheduled && !now.uses_summertime && now.hour.val == 0x01) { | |
increment(now.hour); | |
increment(now.hour); | |
now.uses_summertime = true; | |
} else if (now.timezone_change_scheduled && now.uses_summertime && now.hour.val == 0x02) { | |
now.uses_summertime = false; | |
} else { | |
if (now.hour.val < 0x23) { | |
increment(now.hour); | |
} else if (now.hour.val == 0x23) { | |
now.hour.val = 0x00; | |
if (now.weekday.val < 0x07) { | |
increment(now.weekday); | |
} else if (now.weekday.val == 0x07) { | |
now.weekday.val = 0x01; | |
} | |
if (bcd_to_int(now.day) < days_per_month(now)) { | |
increment(now.day); | |
} else if (bcd_to_int(now.day) == days_per_month(now)) { | |
now.day.val = 0x01; | |
if (now.month.val < 0x12) { | |
increment(now.month); | |
} else if (now.month.val == 0x12) { | |
now.month.val = 0x01; | |
if (now.year.val < 0x99) { | |
increment(now.year); | |
} else if (now.year.val == 0x99) { | |
now.year.val = 0x00; | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
DCF77::tick_t get_current_signal(const DCF77::time_data_t &now) { | |
using namespace Arithmetic_Tools; | |
if (now.second >= 1 && now.second <= 14) { | |
return undefined; | |
} | |
bool result; | |
switch (now.second) { | |
case 0: | |
return short_tick; | |
case 15: | |
if (now.undefined_abnormal_transmitter_operation_output) { return undefined; } | |
result = now.abnormal_transmitter_operation; break; | |
case 16: | |
if (now.undefined_timezone_change_scheduled_output) { return undefined; } | |
result = now.timezone_change_scheduled; break; | |
case 17: | |
if (now.undefined_uses_summertime_output) {return undefined; } | |
result = now.uses_summertime; break; | |
case 18: | |
if (now.undefined_uses_summertime_output) {return undefined; } | |
result = !now.uses_summertime; break; | |
case 19: | |
result = now.leap_second_scheduled; break; | |
case 20: | |
return long_tick; | |
case 21: | |
if (now.undefined_minute_output || now.minute.val > 0x59) { return undefined; } | |
result = now.minute.digit.lo & 0x1; break; | |
case 22: | |
if (now.undefined_minute_output || now.minute.val > 0x59) { return undefined; } | |
result = now.minute.digit.lo & 0x2; break; | |
case 23: | |
if (now.undefined_minute_output || now.minute.val > 0x59) { return undefined; } | |
result = now.minute.digit.lo & 0x4; break; | |
case 24: | |
if (now.undefined_minute_output || now.minute.val > 0x59) { return undefined; } | |
result = now.minute.digit.lo & 0x8; break; | |
case 25: | |
if (now.undefined_minute_output || now.minute.val > 0x59) { return undefined; } | |
result = now.minute.digit.hi & 0x1; break; | |
case 26: | |
if (now.undefined_minute_output || now.minute.val > 0x59) { return undefined; } | |
result = now.minute.digit.hi & 0x2; break; | |
case 27: | |
if (now.undefined_minute_output || now.minute.val > 0x59) { return undefined; } | |
result = now.minute.digit.hi & 0x4; break; | |
case 28: | |
if (now.undefined_minute_output || now.minute.val > 0x59) { return undefined; } | |
result = parity(now.minute.val); break; | |
case 29: | |
if (now.hour.val > 0x23) { return undefined; } | |
result = now.hour.digit.lo & 0x1; break; | |
case 30: | |
if (now.hour.val > 0x23) { return undefined; } | |
result = now.hour.digit.lo & 0x2; break; | |
case 31: | |
if (now.hour.val > 0x23) { return undefined; } | |
result = now.hour.digit.lo & 0x4; break; | |
case 32: | |
if (now.hour.val > 0x23) { return undefined; } | |
result = now.hour.digit.lo & 0x8; break; | |
case 33: | |
if (now.hour.val > 0x23) { return undefined; } | |
result = now.hour.digit.hi & 0x1; break; | |
case 34: | |
if (now.hour.val > 0x23) { return undefined; } | |
result = now.hour.digit.hi & 0x2; break; | |
case 35: | |
if (now.hour.val > 0x23) { return undefined; } | |
result = parity(now.hour.val); break; | |
case 36: | |
if (now.day.val > 0x31) { return undefined; } | |
result = now.day.digit.lo & 0x1; break; | |
case 37: | |
if (now.day.val > 0x31) { return undefined; } | |
result = now.day.digit.lo & 0x2; break; | |
case 38: | |
if (now.day.val > 0x31) { return undefined; } | |
result = now.day.digit.lo & 0x4; break; | |
case 39: | |
if (now.day.val > 0x31) { return undefined; } | |
result = now.day.digit.lo & 0x8; break; | |
case 40: | |
if (now.day.val > 0x31) { return undefined; } | |
result = now.day.digit.hi & 0x1; break; | |
case 41: | |
if (now.day.val > 0x31) { return undefined; } | |
result = now.day.digit.hi & 0x2; break; | |
case 42: | |
if (now.weekday.val > 0x7) { return undefined; } | |
result = now.weekday.val & 0x1; break; | |
case 43: | |
if (now.weekday.val > 0x7) { return undefined; } | |
result = now.weekday.val & 0x2; break; | |
case 44: | |
if (now.weekday.val > 0x7) { return undefined; } | |
result = now.weekday.val & 0x4; break; | |
case 45: | |
if (now.month.val > 0x12) { return undefined; } | |
result = now.month.digit.lo & 0x1; break; | |
case 46: | |
if (now.month.val > 0x12) { return undefined; } | |
result = now.month.digit.lo & 0x2; break; | |
case 47: | |
if (now.month.val > 0x12) { return undefined; } | |
result = now.month.digit.lo & 0x4; break; | |
case 48: | |
if (now.month.val > 0x12) { return undefined; } | |
result = now.month.digit.lo & 0x8; break; | |
case 49: | |
if (now.month.val > 0x12) { return undefined; } | |
result = now.month.digit.hi & 0x1; break; | |
case 50: | |
if (now.year.val > 0x99) { return undefined; } | |
result = now.year.digit.lo & 0x1; break; | |
case 51: | |
if (now.year.val > 0x99) { return undefined; } | |
result = now.year.digit.lo & 0x2; break; | |
case 52: | |
if (now.year.val > 0x99) { return undefined; } | |
result = now.year.digit.lo & 0x4; break; | |
case 53: | |
if (now.year.val > 0x99) { return undefined; } | |
result = now.year.digit.lo & 0x8; break; | |
case 54: | |
if (now.year.val > 0x99) { return undefined; } | |
result = now.year.digit.hi & 0x1; break; | |
case 55: | |
if (now.year.val > 0x99) { return undefined; } | |
result = now.year.digit.hi & 0x2; break; | |
case 56: | |
if (now.year.val > 0x99) { return undefined; } | |
result = now.year.digit.hi & 0x4; break; | |
case 57: | |
if (now.year.val > 0x99) { return undefined; } | |
result = now.year.digit.hi & 0x8; break; | |
case 58: | |
if (now.weekday.val > 0x07 || | |
now.day.val > 0x31 || | |
now.month.val > 0x12 || | |
now.year.val > 0x99) { return undefined; } | |
result = parity(now.day.digit.lo) ^ | |
parity(now.day.digit.hi) ^ | |
parity(now.month.digit.lo) ^ | |
parity(now.month.digit.hi) ^ | |
parity(now.weekday.val) ^ | |
parity(now.year.digit.lo) ^ | |
parity(now.year.digit.hi); break; | |
case 59: | |
if (now.leap_second_scheduled && now.minute.val == 0) { result = 0; break; } | |
case 60: | |
return sync_mark; | |
default: | |
return undefined; | |
} | |
return result? long_tick: short_tick; | |
} | |
void get_serialized_clock_stream(const DCF77::time_data_t &now, DCF77::serialized_clock_stream &data) { | |
using namespace Arithmetic_Tools; | |
data.byte_0 = 0; | |
data.byte_0 = set_bit(data.byte_0, 3, now.timezone_change_scheduled ); | |
data.byte_0 = set_bit(data.byte_0, 4, now.uses_summertime); | |
data.byte_0 = set_bit(data.byte_0, 5, !now.uses_summertime); | |
data.byte_0 = set_bit(data.byte_0, 6, now.leap_second_scheduled); | |
data.byte_0 = set_bit(data.byte_0, 7, 1); | |
data.byte_1 = set_bit(now.minute.val, 7, parity(now.minute.val)); | |
data.byte_2 = set_bit(now.hour.val, 6, parity(now.hour.val)); | |
data.byte_2 = set_bit(data.byte_2, 7, now.day.bit.b0); | |
data.byte_3 = now.day.val>>1 | now.weekday.val<<5; | |
data.byte_4 = now.month.val | now.year.val<<5; | |
const uint8_t date_parity = parity(now.day.digit.lo) ^ | |
parity(now.day.digit.hi) ^ | |
parity(now.month.digit.lo) ^ | |
parity(now.month.digit.hi) ^ | |
parity(now.weekday.val) ^ | |
parity(now.year.digit.lo) ^ | |
parity(now.year.digit.hi); | |
data.byte_5 = set_bit(now.year.val>>3, 5, date_parity); | |
} | |
void debug(const DCF77::time_data_t &clock) { | |
using namespace Debug; | |
Serial.print((reinterpret_cast<const __FlashStringHelper *>((__extension__({static const char __c[] __attribute__((__progmem__)) = (" "); &__c[0];}))))); | |
bcddigits(clock.year.val); | |
Serial.print('.'); | |
bcddigits(clock.month.val); | |
Serial.print('.'); | |
bcddigits(clock.day.val); | |
Serial.print('('); | |
bcddigit(clock.weekday.val); | |
Serial.print(','); | |
bcddigit(weekday(clock)); | |
Serial.print(')'); | |
bcddigits(clock.hour.val); | |
Serial.print(':'); | |
bcddigits(clock.minute.val); | |
Serial.print(':'); | |
if (clock.second < 10) { | |
Serial.print('0'); | |
} | |
Serial.print(clock.second, 10); | |
if (clock.uses_summertime) { | |
Serial.print((reinterpret_cast<const __FlashStringHelper *>((__extension__({static const char __c[] __attribute__((__progmem__)) = (" MESZ "); &__c[0];}))))); | |
} else { | |
Serial.print((reinterpret_cast<const __FlashStringHelper *>((__extension__({static const char __c[] __attribute__((__progmem__)) = (" MEZ "); &__c[0];}))))); | |
} | |
if (clock.leap_second_scheduled) { | |
Serial.print((reinterpret_cast<const __FlashStringHelper *>((__extension__({static const char __c[] __attribute__((__progmem__)) = ("leap second scheduled"); &__c[0];}))))); | |
} | |
if (clock.timezone_change_scheduled) { | |
Serial.print((reinterpret_cast<const __FlashStringHelper *>((__extension__({static const char __c[] __attribute__((__progmem__)) = ("time zone change scheduled"); &__c[0];}))))); | |
} | |
} | |
void debug(const DCF77::time_data_t &clock, const uint16_t cycles) { | |
DCF77::time_data_t local_clock = clock; | |
DCF77::time_data_t decoded_clock; | |
Serial.print((reinterpret_cast<const __FlashStringHelper *>((__extension__({static const char __c[] __attribute__((__progmem__)) = ("M ?????????????? RAZZA S mmmmMMMP hhhhHHP ddddDD www mmmmM yyyyYYYYP S"); &__c[0];}))))); | |
for (uint16_t second = 0; second < cycles; ++second) { | |
switch (local_clock.second) { | |
case 0: Serial.println(); break; | |
case 1: case 15: case 20: case 21: case 29: | |
case 36: case 42: case 45: case 50: case 59: Serial.print(' '); | |
} | |
const DCF77::tick_t tick_data = get_current_signal(local_clock); | |
Debug::debug_helper(tick_data); | |
DCF77_Naive_Bitstream_Decoder::set_bit(local_clock.second, tick_data, decoded_clock); | |
advance_second(local_clock); | |
if (local_clock.second == 0) { | |
debug(decoded_clock); | |
} | |
} | |
Serial.println(); | |
Serial.println(); | |
} | |
} | |
namespace DCF77_Naive_Bitstream_Decoder { | |
using namespace DCF77; | |
void set_bit(const uint8_t second, const uint8_t value, time_data_t &now) { | |
const uint8_t naive_value = (value == long_tick || value == undefined)? 1: 0; | |
const uint8_t is_value_bad = value != long_tick && value != short_tick; | |
now.second = second; | |
switch (second) { | |
case 15: now.abnormal_transmitter_operation = naive_value; break; | |
case 16: now.timezone_change_scheduled = naive_value; break; | |
case 17: | |
now.uses_summertime = naive_value; | |
now.undefined_uses_summertime_output = is_value_bad; | |
break; | |
case 18: | |
if (now.uses_summertime == naive_value) { | |
if (!is_value_bad) { | |
now.uses_summertime = !naive_value; | |
} | |
} | |
now.undefined_uses_summertime_output = false; | |
break; | |
case 19: | |
now.leap_second_scheduled = naive_value && !is_value_bad; | |
break; | |
case 20: | |
now.minute.val = 0x00; | |
now.undefined_minute_output = false; | |
break; | |
case 21: now.minute.val += naive_value; break; | |
case 22: now.minute.val += 0x2*naive_value; break; | |
case 23: now.minute.val += 0x4*naive_value; break; | |
case 24: now.minute.val += 0x8*naive_value; break; | |
case 25: now.minute.val += 0x10*naive_value; break; | |
case 26: now.minute.val += 0x20*naive_value; break; | |
case 27: now.minute.val += 0x40*naive_value; break; | |
case 28: now.hour.val = 0; break; | |
case 29: now.hour.val += naive_value; break; | |
case 30: now.hour.val += 0x2*naive_value; break; | |
case 31: now.hour.val += 0x4*naive_value; break; | |
case 32: now.hour.val += 0x8*naive_value; break; | |
case 33: now.hour.val += 0x10*naive_value; break; | |
case 34: now.hour.val += 0x20*naive_value; break; | |
case 35: | |
now.day.val = 0x00; | |
now.month.val = 0x00; | |
now.year.val = 0x00; | |
now.weekday.val = 0x00; | |
break; | |
case 36: now.day.val += naive_value; break; | |
case 37: now.day.val += 0x2*naive_value; break; | |
case 38: now.day.val += 0x4*naive_value; break; | |
case 39: now.day.val += 0x8*naive_value; break; | |
case 40: now.day.val += 0x10*naive_value; break; | |
case 41: now.day.val += 0x20*naive_value; break; | |
case 42: now.weekday.val += naive_value; break; | |
case 43: now.weekday.val += 0x2*naive_value; break; | |
case 44: now.weekday.val += 0x4*naive_value; break; | |
case 45: now.month.val += naive_value; break; | |
case 46: now.month.val += 0x2*naive_value; break; | |
case 47: now.month.val += 0x4*naive_value; break; | |
case 48: now.month.val += 0x8*naive_value; break; | |
case 49: now.month.val += 0x10*naive_value; break; | |
case 50: now.year.val += naive_value; break; | |
case 51: now.year.val += 0x2*naive_value; break; | |
case 52: now.year.val += 0x4*naive_value; break; | |
case 53: now.year.val += 0x8*naive_value; break; | |
case 54: now.year.val += 0x10*naive_value; break; | |
case 55: now.year.val += 0x20*naive_value; break; | |
case 56: now.year.val += 0x40*naive_value; break; | |
case 57: now.year.val += 0x80*naive_value; break; | |
} | |
} | |
} | |
namespace DCF77_Flag_Decoder { | |
bool abnormal_transmitter_operation; | |
int8_t timezone_change_scheduled; | |
int8_t uses_summertime; | |
int8_t leap_second_scheduled; | |
int8_t date_parity; | |
void setup() { | |
uses_summertime = 0; | |
abnormal_transmitter_operation = 0; | |
timezone_change_scheduled = 0; | |
leap_second_scheduled = 0; | |
date_parity = 0; | |
} | |
void cummulate(int8_t &average, bool count_up) { | |
if (count_up) { | |
average += (average < 127); | |
} else { | |
average -= (average > -127); | |
} | |
} | |
void process_tick(const uint8_t current_second, const uint8_t tick_value) { | |
switch (current_second) { | |
case 15: abnormal_transmitter_operation = tick_value; break; | |
case 16: cummulate(timezone_change_scheduled, tick_value); break; | |
case 17: cummulate(uses_summertime, tick_value); break; | |
case 18: cummulate(uses_summertime, 1-tick_value); break; | |
case 19: cummulate(leap_second_scheduled, tick_value); break; | |
case 58: cummulate(date_parity, tick_value); break; | |
} | |
} | |
void reset_after_previous_hour() { | |
if (timezone_change_scheduled) { | |
timezone_change_scheduled = 0; | |
uses_summertime -= uses_summertime; | |
} | |
leap_second_scheduled = 0; | |
} | |
void reset_before_new_day() { | |
date_parity = 0; | |
} | |
bool get_uses_summertime() { | |
return uses_summertime > 0; | |
} | |
bool get_abnormal_transmitter_operation() { | |
return abnormal_transmitter_operation; | |
} | |
bool get_timezone_change_scheduled() { | |
return timezone_change_scheduled > 0; | |
} | |
bool get_leap_second_scheduled() { | |
return leap_second_scheduled > 0; | |
} | |
void get_quality(uint8_t &uses_summertime_quality, | |
uint8_t &timezone_change_scheduled_quality, | |
uint8_t &leap_second_scheduled_quality) { | |
uses_summertime_quality = ((uses_summertime)>0?(uses_summertime):-(uses_summertime)); | |
timezone_change_scheduled_quality = ((timezone_change_scheduled)>0?(timezone_change_scheduled):-(timezone_change_scheduled)); | |
leap_second_scheduled_quality = ((leap_second_scheduled)>0?(leap_second_scheduled):-(leap_second_scheduled)); | |
} | |
void debug() { | |
Serial.print((reinterpret_cast<const __FlashStringHelper *>((__extension__({static const char __c[] __attribute__((__progmem__)) = ("Backup Antenna, TZ change, TZ, Leap scheduled, Date parity: "); &__c[0];}))))); | |
Serial.print(abnormal_transmitter_operation, 2); | |
Serial.print(','); | |
Serial.print(timezone_change_scheduled, 10); | |
Serial.print(','); | |
Serial.print(uses_summertime, 10); | |
Serial.print(','); | |
Serial.print(leap_second_scheduled, 10); | |
Serial.print(','); | |
Serial.println(date_parity, 10); | |
} | |
} | |
namespace DCF77_Decade_Decoder { | |
const uint8_t decades_per_century = 10; | |
typedef struct { | |
uint8_t data[decades_per_century]; | |
uint8_t tick; | |
uint8_t noise_max; | |
uint8_t max; | |
uint8_t max_index; | |
} decade_bins; | |
decade_bins bins; | |
void advance_decade() { | |
Hamming::advance_tick(bins); | |
} | |
void process_tick(const uint8_t current_second, const uint8_t tick_value) { | |
using namespace Hamming; | |
static BCD::bcd_t decade_data; | |
switch (current_second) { | |
case 54: decade_data.val += tick_value; break; | |
case 55: decade_data.val += 0x02*tick_value; break; | |
case 56: decade_data.val += 0x04*tick_value; break; | |
case 57: decade_data.val += 0x08*tick_value; | |
hamming_binning<decade_bins, 4, false>(bins, decade_data); break; | |
case 58: compute_max_index(bins); | |
default: decade_data.val = 0; | |
} | |
} | |
void get_quality(Hamming::lock_quality_t &lock_quality) { | |
Hamming::get_quality(bins, lock_quality); | |
} | |
uint8_t get_quality_factor() { | |
return Hamming::get_quality_factor(bins); | |
} | |
BCD::bcd_t get_decade() { | |
return Hamming::get_time_value(bins); | |
} | |
void setup() { | |
Hamming::setup(bins); | |
} | |
void debug() { | |
Serial.print((reinterpret_cast<const __FlashStringHelper *>((__extension__({static const char __c[] __attribute__((__progmem__)) = ("Decade: "); &__c[0];}))))); | |
Hamming::debug(bins); | |
} | |
} | |
namespace DCF77_Year_Decoder { | |
const uint8_t years_per_century = 10; | |
typedef struct { | |
uint8_t data[years_per_century]; | |
uint8_t tick; | |
uint8_t noise_max; | |
uint8_t max; | |
uint8_t max_index; | |
} year_bins; | |
year_bins bins; | |
void advance_year() { | |
Hamming::advance_tick(bins); | |
if (Hamming::get_time_value(bins).val == 0) { | |
DCF77_Decade_Decoder::advance_decade(); | |
} | |
} | |
void process_tick(const uint8_t current_second, const uint8_t tick_value) { | |
using namespace Hamming; | |
static BCD::bcd_t year_data; | |
switch (current_second) { | |
case 50: year_data.val += tick_value; break; | |
case 51: year_data.val += 0x2*tick_value; break; | |
case 52: year_data.val += 0x4*tick_value; break; | |
case 53: year_data.val += 0x8*tick_value; | |
hamming_binning<year_bins, 4, false>(bins, year_data); break; | |
case 54: compute_max_index(bins); | |
default: year_data.val = 0; | |
} | |
DCF77_Decade_Decoder::process_tick(current_second, tick_value); | |
} | |
void get_quality(Hamming::lock_quality_t &lock_quality) { | |
Hamming::get_quality(bins, lock_quality); | |
Hamming::lock_quality_t decade_lock_quality; | |
DCF77_Decade_Decoder::get_quality(decade_lock_quality); | |
Arithmetic_Tools::minimize(lock_quality.lock_max, decade_lock_quality.lock_max); | |
Arithmetic_Tools::maximize(lock_quality.noise_max, decade_lock_quality.noise_max); | |
} | |
uint8_t get_quality_factor() { | |
const uint8_t qf_years = Hamming::get_quality_factor(bins); | |
const uint8_t qf_decades = DCF77_Decade_Decoder::get_quality_factor(); | |
return ((qf_years)<(qf_decades)?(qf_years):(qf_decades)); | |
} | |
BCD::bcd_t get_year() { | |
BCD::bcd_t year = Hamming::get_time_value(bins); | |
BCD::bcd_t decade = DCF77_Decade_Decoder::get_decade(); | |
if (year.val == 0xff || decade.val == 0xff) { | |
year.val = 0xff; | |
} else { | |
year.val += decade.val << 4; | |
} | |
return year; | |
} | |
void setup() { | |
Hamming::setup(bins); | |
DCF77_Decade_Decoder::setup(); | |
} | |
void debug() { | |
Serial.print((reinterpret_cast<const __FlashStringHelper *>((__extension__({static const char __c[] __attribute__((__progmem__)) = ("Year: "); &__c[0];}))))); | |
Hamming::debug(bins); | |
DCF77_Decade_Decoder::debug(); | |
} | |
} | |
namespace DCF77_Month_Decoder { | |
const uint8_t months_per_year = 12; | |
typedef struct { | |
uint8_t data[months_per_year]; | |
uint8_t tick; | |
uint8_t noise_max; | |
uint8_t max; | |
uint8_t max_index; | |
} month_bins; | |
month_bins bins; | |
void advance_month() { | |
Hamming::advance_tick(bins); | |
} | |
void process_tick(const uint8_t current_second, const uint8_t tick_value) { | |
using namespace Hamming; | |
static BCD::bcd_t month_data; | |
switch (current_second) { | |
case 45: month_data.val += tick_value; break; | |
case 46: month_data.val += 0x2*tick_value; break; | |
case 47: month_data.val += 0x4*tick_value; break; | |
case 48: month_data.val += 0x8*tick_value; break; | |
case 49: month_data.val += 0x10*tick_value; | |
hamming_binning<month_bins, 5, false>(bins, month_data); break; | |
case 50: compute_max_index(bins); | |
default: month_data.val = 0; | |
} | |
} | |
void get_quality(Hamming::lock_quality_t &lock_quality) { | |
Hamming::get_quality(bins, lock_quality); | |
} | |
uint8_t get_quality_factor() { | |
return Hamming::get_quality_factor(bins); | |
} | |
BCD::bcd_t get_month() { | |
return Hamming::get_time_value(bins); | |
} | |
void setup() { | |
Hamming::setup(bins); | |
} | |
void debug() { | |
Serial.print((reinterpret_cast<const __FlashStringHelper *>((__extension__({static const char __c[] __attribute__((__progmem__)) = ("Month: "); &__c[0];}))))); | |
Hamming::debug(bins); | |
} | |
} | |
namespace DCF77_Weekday_Decoder { | |
const uint8_t weekdays_per_week = 7; | |
typedef struct { | |
uint8_t data[weekdays_per_week]; | |
uint8_t tick; | |
uint8_t noise_max; | |
uint8_t max; | |
uint8_t max_index; | |
} weekday_bins; | |
weekday_bins bins; | |
void advance_weekday() { | |
Hamming::advance_tick(bins); | |
} | |
void process_tick(const uint8_t current_second, const uint8_t tick_value) { | |
using namespace Hamming; | |
static BCD::bcd_t weekday_data; | |
switch (current_second) { | |
case 42: weekday_data.val += tick_value; break; | |
case 43: weekday_data.val += 0x2*tick_value; break; | |
case 44: weekday_data.val += 0x4*tick_value; | |
hamming_binning<weekday_bins, 3, false>(bins, weekday_data); break; | |
case 45: compute_max_index(bins); | |
default: weekday_data.val = 0; | |
} | |
} | |
void get_quality(Hamming::lock_quality_t &lock_quality) { | |
Hamming::get_quality(bins, lock_quality); | |
} | |
uint8_t get_quality_factor() { | |
return Hamming::get_quality_factor(bins); | |
} | |
BCD::bcd_t get_weekday() { | |
return Hamming::get_time_value(bins); | |
} | |
void setup() { | |
Hamming::setup(bins); | |
} | |
void debug() { | |
Serial.print((reinterpret_cast<const __FlashStringHelper *>((__extension__({static const char __c[] __attribute__((__progmem__)) = ("Weekday: "); &__c[0];}))))); | |
Hamming::debug(bins); | |
} | |
} | |
namespace DCF77_Day_Decoder { | |
const uint8_t days_per_month = 31; | |
typedef struct { | |
uint8_t data[days_per_month]; | |
uint8_t tick; | |
uint8_t noise_max; | |
uint8_t max; | |
uint8_t max_index; | |
} day_bins; | |
day_bins bins; | |
void advance_day() { | |
Hamming::advance_tick(bins); | |
} | |
void process_tick(const uint8_t current_second, const uint8_t tick_value) { | |
using namespace Hamming; | |
static BCD::bcd_t day_data; | |
switch (current_second) { | |
case 36: day_data.val += tick_value; break; | |
case 37: day_data.val += 0x2*tick_value; break; | |
case 38: day_data.val += 0x4*tick_value; break; | |
case 39: day_data.val += 0x8*tick_value; break; | |
case 40: day_data.val += 0x10*tick_value; break; | |
case 41: day_data.val += 0x20*tick_value; | |
hamming_binning<day_bins, 6, false>(bins, day_data); break; | |
case 42: compute_max_index(bins); | |
default: day_data.val = 0; | |
} | |
} | |
void get_quality(Hamming::lock_quality_t &lock_quality) { | |
Hamming::get_quality(bins, lock_quality); | |
} | |
uint8_t get_quality_factor() { | |
return Hamming::get_quality_factor(bins); | |
} | |
BCD::bcd_t get_day() { | |
return Hamming::get_time_value(bins); | |
} | |
void setup() { | |
Hamming::setup(bins); | |
} | |
void debug() { | |
Serial.print((reinterpret_cast<const __FlashStringHelper *>((__extension__({static const char __c[] __attribute__((__progmem__)) = ("Day: "); &__c[0];}))))); | |
Hamming::debug(bins); | |
} | |
} | |
namespace DCF77_Hour_Decoder { | |
const uint8_t hours_per_day = 24; | |
typedef struct { | |
uint8_t data[hours_per_day]; | |
uint8_t tick; | |
uint8_t noise_max; | |
uint8_t max; | |
uint8_t max_index; | |
} hour_bins; | |
hour_bins bins; | |
void advance_hour() { | |
Hamming::advance_tick(bins); | |
} | |
void process_tick(const uint8_t current_second, const uint8_t tick_value) { | |
using namespace Hamming; | |
static BCD::bcd_t hour_data; | |
switch (current_second) { | |
case 29: hour_data.val += tick_value; break; | |
case 30: hour_data.val += 0x2*tick_value; break; | |
case 31: hour_data.val += 0x4*tick_value; break; | |
case 32: hour_data.val += 0x8*tick_value; break; | |
case 33: hour_data.val += 0x10*tick_value; break; | |
case 34: hour_data.val += 0x20*tick_value; break; | |
case 35: hour_data.val += 0x80*tick_value; | |
hamming_binning<hour_bins, 7, true>(bins, hour_data); break; | |
case 36: compute_max_index(bins); | |
default: hour_data.val = 0; | |
} | |
} | |
void get_quality(Hamming::lock_quality_t &lock_quality) { | |
Hamming::get_quality(bins, lock_quality); | |
} | |
uint8_t get_quality_factor() { | |
return Hamming::get_quality_factor(bins); | |
} | |
BCD::bcd_t get_hour() { | |
return Hamming::get_time_value(bins); | |
} | |
void setup() { | |
Hamming::setup(bins); | |
} | |
void debug() { | |
Serial.print((reinterpret_cast<const __FlashStringHelper *>((__extension__({static const char __c[] __attribute__((__progmem__)) = ("Hour: "); &__c[0];}))))); | |
Hamming::debug(bins); | |
} | |
} | |
namespace DCF77_Minute_Decoder { | |
const uint8_t minutes_per_hour = 60; | |
typedef struct { | |
uint8_t data[minutes_per_hour]; | |
uint8_t tick; | |
uint8_t noise_max; | |
uint8_t max; | |
uint8_t max_index; | |
} minute_bins; | |
minute_bins bins; | |
void advance_minute() { | |
Hamming::advance_tick(bins); | |
} | |
void process_tick(const uint8_t current_second, const uint8_t tick_value) { | |
using namespace Hamming; | |
static BCD::bcd_t minute_data; | |
switch (current_second) { | |
case 21: minute_data.val += tick_value; break; | |
case 22: minute_data.val += 0x2*tick_value; break; | |
case 23: minute_data.val += 0x4*tick_value; break; | |
case 24: minute_data.val += 0x8*tick_value; break; | |
case 25: minute_data.val += 0x10*tick_value; break; | |
case 26: minute_data.val += 0x20*tick_value; break; | |
case 27: minute_data.val += 0x40*tick_value; break; | |
case 28: minute_data.val += 0x80*tick_value; | |
hamming_binning<minute_bins, 8, true>(bins, minute_data); break; | |
case 29: compute_max_index(bins); | |
default: minute_data.val = 0; | |
} | |
} | |
void setup() { | |
Hamming::setup(bins); | |
} | |
void get_quality(Hamming::lock_quality_t &lock_quality) { | |
Hamming::get_quality(bins, lock_quality); | |
} | |
uint8_t get_quality_factor() { | |
return Hamming::get_quality_factor(bins); | |
} | |
BCD::bcd_t get_minute() { | |
return Hamming::get_time_value(bins); | |
} | |
void debug() { | |
Serial.print((reinterpret_cast<const __FlashStringHelper *>((__extension__({static const char __c[] __attribute__((__progmem__)) = ("Minute: "); &__c[0];}))))); | |
Hamming::debug(bins); | |
} | |
} | |
namespace DCF77_Second_Decoder { | |
using namespace DCF77; | |
const uint8_t seconds_per_minute = 60; | |
const uint8_t lock_threshold = 12; | |
typedef struct { | |
uint8_t data[seconds_per_minute]; | |
uint8_t tick; | |
uint8_t noise_max; | |
uint8_t max; | |
uint8_t max_index; | |
} sync_bins; | |
sync_bins bins; | |
serialized_clock_stream convolution_kernel; | |
const uint8_t convolution_binning_not_ready = 0xff; | |
uint8_t prediction_match = convolution_binning_not_ready; | |
uint8_t buffered_match = convolution_binning_not_ready; | |
uint8_t get_prediction_match() { | |
return buffered_match; | |
}; | |
void set_convolution_time(const DCF77::time_data_t &now) { | |
DCF77::time_data_t convolution_clock = now; | |
DCF77_Encoder::advance_minute(convolution_clock); | |
DCF77_Encoder::autoset_control_bits(convolution_clock); | |
DCF77_Encoder::get_serialized_clock_stream(convolution_clock, convolution_kernel); | |
prediction_match = 0; | |
} | |
void convolution_binning(const uint8_t tick_data) { | |
using namespace Arithmetic_Tools; | |
if (bins.max - bins.noise_max <= lock_threshold || get_second() == 3) { | |
Hamming::compute_max_index(bins); | |
const uint8_t convolution_weight = 50; | |
if (bins.max > 255-convolution_weight) { | |
for (uint8_t bin_index = 0; bin_index < seconds_per_minute; ++bin_index) { | |
bounded_decrement<convolution_weight>(bins.data[bin_index]); | |
} | |
bins.max -= convolution_weight; | |
bounded_decrement<convolution_weight>(bins.noise_max); | |
} | |
buffered_match = prediction_match; | |
} | |
if (tick_data == sync_mark) { | |
bounded_increment<6>(bins.data[bins.tick]); | |
if (bins.tick == bins.max_index) { | |
prediction_match += 6; | |
} | |
} else if (tick_data == short_tick || tick_data == long_tick) { | |
uint8_t decoded_bit = (tick_data == long_tick); | |
uint8_t bin = bins.tick>0? bins.tick-1: seconds_per_minute-1; | |
const bool is_match = (decoded_bit == 0); | |
bins.data[bin] += is_match; | |
if (bin == bins.max_index) { | |
prediction_match += is_match; | |
} | |
bin = bin>15? bin-16: bin + seconds_per_minute-16; | |
uint8_t current_byte_index = 0; | |
uint8_t current_bit_index = 3; | |
uint8_t current_byte_value = convolution_kernel.byte_0 >> 3; | |
while (current_byte_index < 6) { | |
while (current_bit_index < 8) { | |
const uint8_t current_bit_value = current_byte_value & 1; | |
const bool is_match = (decoded_bit == current_bit_value); | |
bins.data[bin] += is_match; | |
if (bin == bins.max_index) { | |
prediction_match += is_match; | |
} | |
bin = bin>0? bin-1: seconds_per_minute-1; | |
current_byte_value >>= 1; | |
++current_bit_index; | |
if (current_byte_index == 5 && current_bit_index > 5) { | |
break; | |
} | |
} | |
current_bit_index = 0; | |
++current_byte_index; | |
current_byte_value = (&(convolution_kernel.byte_0))[current_byte_index]; | |
} | |
} | |
bins.tick = bins.tick<seconds_per_minute-1? bins.tick+1: 0; | |
} | |
void sync_mark_binning(const uint8_t tick_data) { | |
# 1718 "C:\\Documents and Settings\\STEFANOD\\Documenti\\Arduino\\libraries\\dcf77_library\\dcf77.cpp" | |
using namespace Arithmetic_Tools; | |
const uint8_t previous_tick = bins.tick>0? bins.tick-1: seconds_per_minute-1; | |
const uint8_t previous_21_tick = bins.tick>20? bins.tick-21: bins.tick + seconds_per_minute-21; | |
switch (tick_data) { | |
case sync_mark: | |
bounded_increment<6>(bins.data[bins.tick]); | |
bounded_decrement<2>(bins.data[previous_tick]); | |
bounded_decrement<2>(bins.data[previous_21_tick]); | |
{ const uint8_t next_tick = bins.tick< seconds_per_minute-1? bins.tick+1: 0; | |
bounded_decrement<2>(bins.data[next_tick]); } | |
break; | |
case short_tick: | |
bounded_increment<1>(bins.data[previous_tick]); | |
bounded_decrement<2>(bins.data[bins.tick]); | |
bounded_decrement<2>(bins.data[previous_21_tick]); | |
break; | |
case long_tick: | |
bounded_increment<1>(bins.data[previous_21_tick]); | |
bounded_decrement<2>(bins.data[bins.tick]); | |
bounded_decrement<2>(bins.data[previous_tick]); | |
break; | |
case undefined: | |
default: | |
bounded_decrement<2>(bins.data[bins.tick]); | |
bounded_decrement<2>(bins.data[previous_tick]); | |
bounded_decrement<2>(bins.data[previous_21_tick]); | |
} | |
bins.tick = bins.tick<seconds_per_minute-1? bins.tick+1: 0; | |
if (bins.max - bins.noise_max <=lock_threshold || | |
get_second() == 3) { | |
Hamming::compute_max_index(bins); | |
} | |
} | |
void get_quality(Hamming::lock_quality_t &lock_quality) { | |
Hamming::get_quality(bins, lock_quality); | |
} | |
uint8_t get_quality_factor() { | |
return Hamming::get_quality_factor(bins); | |
} | |
uint8_t get_second() { | |
if (bins.max - bins.noise_max >= lock_threshold) { | |
# 1790 "C:\\Documents and Settings\\STEFANOD\\Documenti\\Arduino\\libraries\\dcf77_library\\dcf77.cpp" | |
uint8_t second = 2*seconds_per_minute + bins.tick - 2 - bins.max_index; | |
while (second >= seconds_per_minute) { second-= seconds_per_minute; } | |
return second; | |
} else { | |
return 0xff; | |
} | |
} | |
void process_single_tick_data(const DCF77::tick_t tick_data) { | |
if (prediction_match == convolution_binning_not_ready) { | |
sync_mark_binning(tick_data); | |
} else { | |
convolution_binning(tick_data); | |
} | |
} | |
void setup() { | |
Hamming::setup(bins); | |
} | |
void debug() { | |
static uint8_t prev_tick; | |
if (prev_tick == bins.tick) { | |
return; | |
} else { | |
prev_tick = bins.tick; | |
Serial.print((reinterpret_cast<const __FlashStringHelper *>((__extension__({static const char __c[] __attribute__((__progmem__)) = ("second: "); &__c[0];}))))); | |
Serial.print(get_second(), 10); | |
Serial.print((reinterpret_cast<const __FlashStringHelper *>((__extension__({static const char __c[] __attribute__((__progmem__)) = (" Sync mark index "); &__c[0];}))))); | |
Hamming::debug(bins); | |
Serial.print((reinterpret_cast<const __FlashStringHelper *>((__extension__({static const char __c[] __attribute__((__progmem__)) = ("Prediction Match: "); &__c[0];}))))); | |
Serial.println(prediction_match, 10); | |
Serial.println(); | |
} | |
} | |
} | |
namespace DCF77_Local_Clock { | |
clock_state_t clock_state = useless; | |
DCF77::output_handler_t output_handler = 0; | |
DCF77::time_data_t local_clock_time; | |
volatile bool second_toggle; | |
uint16_t tick = 0; | |
uint32_t unlocked_seconds = 0; | |
void setup() { | |
DCF77_Encoder::reset(local_clock_time); | |
} | |
void read_current_time(DCF77::time_data_t &now) { | |
const uint8_t prev_SREG = (*(volatile uint8_t *)((0x3F) + 0x20)); | |
__asm__ __volatile__ ("cli" ::: "memory"); | |
now = local_clock_time; | |
(*(volatile uint8_t *)((0x3F) + 0x20)) = prev_SREG; | |
} | |
void get_current_time(DCF77::time_data_t &now) { | |
for (bool stopper = second_toggle; stopper == second_toggle; ) { | |
} | |
read_current_time(now); | |
} | |
void process_1_Hz_tick(const DCF77::time_data_t &decoded_time) { | |
uint8_t quality_factor = DCF77_Clock_Controller::get_overall_quality_factor(); | |
if (quality_factor > 1) { | |
if (clock_state != synced) { | |
DCF77_Clock_Controller::sync_achieved_event_handler(); | |
clock_state = synced; | |
} | |
} else if (clock_state == synced) { | |
DCF77_Clock_Controller::sync_lost_event_handler(); | |
clock_state = locked; | |
} | |
while (true) { | |
switch (clock_state) { | |
case useless: { | |
if (quality_factor > 0) { | |
clock_state = dirty; | |
break; | |
} else { | |
second_toggle = !second_toggle; | |
return; | |
} | |
} | |
case dirty: { | |
if (quality_factor == 0) { | |
clock_state = useless; | |
second_toggle = !second_toggle; | |
DCF77_Encoder::reset(local_clock_time); | |
return; | |
} else { | |
tick = 0; | |
local_clock_time = decoded_time; | |
DCF77_Clock_Controller::flush(decoded_time); | |
second_toggle = !second_toggle; | |
return; | |
} | |
} | |
case synced: { | |
tick = 0; | |
local_clock_time = decoded_time; | |
DCF77_Clock_Controller::flush(decoded_time); | |
second_toggle = !second_toggle; | |
return; | |
} | |
case locked: { | |
if (DCF77_Demodulator::get_quality_factor() > 10) { | |
local_clock_time.leap_second_scheduled = false; | |
DCF77_Encoder::advance_second(local_clock_time); | |
DCF77_Clock_Controller::flush(local_clock_time); | |
tick = 0; | |
second_toggle = !second_toggle; | |
return; | |
} else { | |
clock_state = unlocked; | |
DCF77_Clock_Controller::phase_lost_event_handler(); | |
unlocked_seconds = 0; | |
return; | |
} | |
} | |
case unlocked: { | |
if (DCF77_Demodulator::get_quality_factor() > 10) { | |
if (200 < tick && tick < 800) { | |
return; | |
} else { | |
clock_state = locked; | |
if (tick < 200) { | |
tick = 0; | |
return; | |
} else { | |
break; | |
} | |
} | |
} else { | |
return; | |
} | |
} | |
case free: { | |
return; | |
} | |
} | |
} | |
} | |
uint32_t max_unlocked_seconds = 3000; | |
void set_has_tuned_clock() { | |
max_unlocked_seconds = 30000; | |
}; | |
void process_1_kHz_tick() { | |
++tick; | |
if (clock_state == synced || clock_state == locked) { | |
if (tick >= 1150) { | |
unlocked_seconds = 1; | |
clock_state = unlocked; | |
DCF77_Clock_Controller::phase_lost_event_handler(); | |
} | |
} | |
if (clock_state == unlocked || clock_state == free) { | |
if (tick >= 1000) { | |
tick -= 1000; | |
local_clock_time.leap_second_scheduled = false; | |
DCF77_Encoder::advance_second(local_clock_time); | |
DCF77_Clock_Controller::flush(local_clock_time); | |
second_toggle = !second_toggle; | |
++unlocked_seconds; | |
if (unlocked_seconds > max_unlocked_seconds) { | |
clock_state = free; | |
} | |
} | |
} | |
} | |
void set_output_handler(const DCF77::output_handler_t new_output_handler) { | |
output_handler = new_output_handler; | |
} | |
clock_state_t get_state() { | |
return clock_state; | |
} | |
void debug() { | |
Serial.print((reinterpret_cast<const __FlashStringHelper *>((__extension__({static const char __c[] __attribute__((__progmem__)) = ("Clock state: "); &__c[0];}))))); | |
switch (clock_state) { | |
case useless: Serial.println((reinterpret_cast<const __FlashStringHelper *>((__extension__({static const char __c[] __attribute__((__progmem__)) = ("useless"); &__c[0];}))))); break; | |
case dirty: Serial.println((reinterpret_cast<const __FlashStringHelper *>((__extension__({static const char __c[] __attribute__((__progmem__)) = ("dirty"); &__c[0];}))))); break; | |
case free: Serial.println((reinterpret_cast<const __FlashStringHelper *>((__extension__({static const char __c[] __attribute__((__progmem__)) = ("free"); &__c[0];}))))); break; | |
case unlocked: Serial.println((reinterpret_cast<const __FlashStringHelper *>((__extension__({static const char __c[] __attribute__((__progmem__)) = ("unlocked"); &__c[0];}))))); break; | |
case locked: Serial.println((reinterpret_cast<const __FlashStringHelper *>((__extension__({static const char __c[] __attribute__((__progmem__)) = ("locked"); &__c[0];}))))); break; | |
case synced: Serial.println((reinterpret_cast<const __FlashStringHelper *>((__extension__({static const char __c[] __attribute__((__progmem__)) = ("synced"); &__c[0];}))))); break; | |
default: Serial.println((reinterpret_cast<const __FlashStringHelper *>((__extension__({static const char __c[] __attribute__((__progmem__)) = ("undefined"); &__c[0];}))))); | |
} | |
Serial.print((reinterpret_cast<const __FlashStringHelper *>((__extension__({static const char __c[] __attribute__((__progmem__)) = ("Tick: "); &__c[0];}))))); | |
Serial.println(tick); | |
} | |
} | |
namespace DCF77_Clock_Controller { | |
uint8_t leap_second = 0; | |
DCF77_Clock::output_handler_t output_handler = 0; | |
DCF77::time_data_t decoded_time; | |
void get_current_time(DCF77::time_data_t &now) { | |
auto_persist(); | |
DCF77_Local_Clock::get_current_time(now); | |
} | |
void read_current_time(DCF77::time_data_t &now) { | |
DCF77_Local_Clock::read_current_time(now); | |
} | |
void auto_persist() { | |
DCF77_Frequency_Control::auto_persist(); | |
} | |
void on_tuned_clock() { | |
DCF77_Demodulator::set_has_tuned_clock(); | |
DCF77_Local_Clock::set_has_tuned_clock(); | |
}; | |
void set_DCF77_encoder(DCF77::time_data_t &now) { | |
using namespace DCF77_Second_Decoder; | |
using namespace DCF77_Minute_Decoder; | |
using namespace DCF77_Hour_Decoder; | |
using namespace DCF77_Weekday_Decoder; | |
using namespace DCF77_Day_Decoder; | |
using namespace DCF77_Month_Decoder; | |
using namespace DCF77_Year_Decoder; | |
using namespace DCF77_Flag_Decoder; | |
now.second = get_second(); | |
now.minute = get_minute(); | |
now.hour = get_hour(); | |
now.weekday = get_weekday(); | |
now.day = get_day(); | |
now.month = get_month(); | |
now.year = get_year(); | |
now.abnormal_transmitter_operation = get_abnormal_transmitter_operation(); | |
now.timezone_change_scheduled = get_timezone_change_scheduled(); | |
now.uses_summertime = get_uses_summertime(); | |
now.leap_second_scheduled = get_leap_second_scheduled(); | |
} | |
void flush() { | |
DCF77::time_data_t now; | |
DCF77::time_data_t now_1; | |
set_DCF77_encoder(now); | |
now_1 = now; | |
now.second += leap_second > 0; | |
DCF77_Encoder::advance_second(now); | |
DCF77_Encoder::autoset_control_bits(now); | |
decoded_time.second = now.second; | |
if (now.second == 0) { | |
decoded_time = now_1; | |
decoded_time.second = 0; | |
if (now.minute.val == 0x01) { | |
DCF77_Flag_Decoder::reset_after_previous_hour(); | |
now.uses_summertime = DCF77_Flag_Decoder::get_uses_summertime(); | |
now.timezone_change_scheduled = DCF77_Flag_Decoder::get_timezone_change_scheduled(); | |
now.leap_second_scheduled = DCF77_Flag_Decoder::get_leap_second_scheduled(); | |
DCF77_Encoder::autoset_control_bits(now); | |
decoded_time.uses_summertime = now.uses_summertime; | |
decoded_time.timezone_change_scheduled = now.timezone_change_scheduled; | |
decoded_time.leap_second_scheduled = now.leap_second_scheduled; | |
decoded_time.abnormal_transmitter_operation = DCF77_Flag_Decoder::get_abnormal_transmitter_operation(); | |
} | |
if (now.hour.val == 0x23 && now.minute.val == 0x59) { | |
DCF77_Flag_Decoder::reset_before_new_day(); | |
} | |
leap_second &= leap_second < 2; | |
} | |
DCF77_Local_Clock::process_1_Hz_tick(decoded_time); | |
} | |
void flush(const DCF77::time_data_t &decoded_time) { | |
# 2163 "C:\\Documents and Settings\\STEFANOD\\Documenti\\Arduino\\libraries\\dcf77_library\\dcf77.cpp" | |
DCF77_Frequency_Control::process_1_Hz_tick(decoded_time); | |
if (output_handler) { | |
DCF77_Clock::time_t time; | |
time.second = BCD::int_to_bcd(decoded_time.second); | |
time.minute = decoded_time.minute; | |
time.hour = decoded_time.hour; | |
time.weekday = decoded_time.weekday; | |
time.day = decoded_time.day; | |
time.month = decoded_time.month; | |
time.year = decoded_time.year; | |
time.uses_summertime = decoded_time.uses_summertime; | |
time.leap_second_scheduled = decoded_time.leap_second_scheduled; | |
time.timezone_change_scheduled = decoded_time.timezone_change_scheduled; | |
output_handler(time); | |
} | |
if (decoded_time.second == 15 && DCF77_Local_Clock::clock_state != DCF77_Local_Clock::useless | |
&& DCF77_Local_Clock::clock_state != DCF77_Local_Clock::dirty | |
) { | |
DCF77_Second_Decoder::set_convolution_time(decoded_time); | |
} | |
} | |
void process_1_kHz_tick_data(const uint8_t sampled_data) { | |
DCF77_Demodulator::detector(sampled_data); | |
DCF77_Local_Clock::process_1_kHz_tick(); | |
DCF77_Frequency_Control::process_1_kHz_tick(); | |
} | |
void set_output_handler(const DCF77_Clock::output_handler_t new_output_handler) { | |
output_handler = new_output_handler; | |
} | |
void get_quality(clock_quality_t &clock_quality) { | |
DCF77_Demodulator::get_quality(clock_quality.phase.lock_max, clock_quality.phase.noise_max); | |
DCF77_Second_Decoder::get_quality(clock_quality.second); | |
DCF77_Minute_Decoder::get_quality(clock_quality.minute); | |
DCF77_Hour_Decoder::get_quality(clock_quality.hour); | |
DCF77_Day_Decoder::get_quality(clock_quality.day); | |
DCF77_Weekday_Decoder::get_quality(clock_quality.weekday); | |
DCF77_Month_Decoder::get_quality(clock_quality.month); | |
DCF77_Year_Decoder::get_quality(clock_quality.year); | |
DCF77_Flag_Decoder::get_quality(clock_quality.uses_summertime_quality, | |
clock_quality.timezone_change_scheduled_quality, | |
clock_quality.leap_second_scheduled_quality); | |
} | |
void get_quality_factor(clock_quality_factor_t &clock_quality_factor) { | |
clock_quality_factor.phase = DCF77_Demodulator::get_quality_factor(); | |
clock_quality_factor.second = DCF77_Second_Decoder::get_quality_factor(); | |
clock_quality_factor.minute = DCF77_Minute_Decoder::get_quality_factor(); | |
clock_quality_factor.hour = DCF77_Hour_Decoder::get_quality_factor(); | |
clock_quality_factor.day = DCF77_Day_Decoder::get_quality_factor(); | |
clock_quality_factor.weekday = DCF77_Weekday_Decoder::get_quality_factor(); | |
clock_quality_factor.month = DCF77_Month_Decoder::get_quality_factor(); | |
clock_quality_factor.year = DCF77_Year_Decoder::get_quality_factor(); | |
} | |
uint8_t get_overall_quality_factor() { | |
using namespace Arithmetic_Tools; | |
uint8_t quality_factor = DCF77_Demodulator::get_quality_factor(); | |
minimize(quality_factor, DCF77_Second_Decoder::get_quality_factor()); | |
minimize(quality_factor, DCF77_Minute_Decoder::get_quality_factor()); | |
minimize(quality_factor, DCF77_Hour_Decoder::get_quality_factor()); | |
uint8_t date_quality_factor = DCF77_Day_Decoder::get_quality_factor(); | |
minimize(date_quality_factor, DCF77_Month_Decoder::get_quality_factor()); | |
minimize(date_quality_factor, DCF77_Year_Decoder::get_quality_factor()); | |
const uint8_t weekday_quality_factor = DCF77_Weekday_Decoder::get_quality_factor(); | |
if (date_quality_factor > 0 && weekday_quality_factor > 0) { | |
DCF77::time_data_t now; | |
now.second = DCF77_Second_Decoder::get_second(); | |
now.minute = DCF77_Minute_Decoder::get_minute(); | |
now.hour = DCF77_Hour_Decoder::get_hour(); | |
now.weekday = DCF77_Weekday_Decoder::get_weekday(); | |
now.day = DCF77_Day_Decoder::get_day(); | |
now.month = DCF77_Month_Decoder::get_month(); | |
now.year = DCF77_Year_Decoder::get_year(); | |
BCD::bcd_t weekday = DCF77_Encoder::bcd_weekday(now); | |
if (weekday.val == 0) { | |
weekday.val = 7; | |
} | |
if (now.weekday.val == weekday.val) { | |
date_quality_factor += 1; | |
} else if (date_quality_factor <= weekday_quality_factor) { | |
date_quality_factor = 0; | |
} | |
} | |
minimize(quality_factor, date_quality_factor); | |
return quality_factor; | |
}; | |
uint8_t get_clock_state() { | |
return DCF77_Local_Clock::get_state(); | |
} | |
uint8_t get_prediction_match() { | |
return DCF77_Second_Decoder::get_prediction_match(); | |
} | |
void debug() { | |
clock_quality_t clock_quality; | |
get_quality(clock_quality); | |
clock_quality_factor_t clock_quality_factor; | |
get_quality_factor(clock_quality_factor); | |
Serial.print((reinterpret_cast<const __FlashStringHelper *>((__extension__({static const char __c[] __attribute__((__progmem__)) = ("Quality (p,s,m,h,wd,d,m,y,st,tz,ls,pm): "); &__c[0];}))))); | |
Serial.print(get_overall_quality_factor(), 10); | |
Serial.print((reinterpret_cast<const __FlashStringHelper *>((__extension__({static const char __c[] __attribute__((__progmem__)) = (" ("); &__c[0];}))))); | |
Serial.print(clock_quality.phase.lock_max, 10); | |
Serial.print('-'); | |
Serial.print(clock_quality.phase.noise_max, 10); | |
Serial.print(':'); | |
Serial.print(clock_quality_factor.phase, 10); | |
Serial.print(')'); | |
Serial.print('('); | |
Serial.print(clock_quality.second.lock_max, 10); | |
Serial.print('-'); | |
Serial.print(clock_quality.second.noise_max, 10); | |
Serial.print(':'); | |
Serial.print(clock_quality_factor.second, 10); | |
Serial.print(')'); | |
Serial.print('('); | |
Serial.print(clock_quality.minute.lock_max, 10); | |
Serial.print('-'); | |
Serial.print(clock_quality.minute.noise_max, 10); | |
Serial.print(':'); | |
Serial.print(clock_quality_factor.minute, 10); | |
Serial.print(')'); | |
Serial.print('('); | |
Serial.print(clock_quality.hour.lock_max, 10); | |
Serial.print('-'); | |
Serial.print(clock_quality.hour.noise_max, 10); | |
Serial.print(':'); | |
Serial.print(clock_quality_factor.hour, 10); | |
Serial.print(')'); | |
Serial.print('('); | |
Serial.print(clock_quality.weekday.lock_max, 10); | |
Serial.print('-'); | |
Serial.print(clock_quality.weekday.noise_max, 10); | |
Serial.print(':'); | |
Serial.print(clock_quality_factor.weekday, 10); | |
Serial.print(')'); | |
Serial.print('('); | |
Serial.print(clock_quality.day.lock_max, 10); | |
Serial.print('-'); | |
Serial.print(clock_quality.day.noise_max, 10); | |
Serial.print(':'); | |
Serial.print(clock_quality_factor.day, 10); | |
Serial.print(')'); | |
Serial.print('('); | |
Serial.print(clock_quality.month.lock_max, 10); | |
Serial.print('-'); | |
Serial.print(clock_quality.month.noise_max, 10); | |
Serial.print(':'); | |
Serial.print(clock_quality_factor.month, 10); | |
Serial.print(')'); | |
Serial.print('('); | |
Serial.print(clock_quality.year.lock_max, 10); | |
Serial.print('-'); | |
Serial.print(clock_quality.year.noise_max, 10); | |
Serial.print(':'); | |
Serial.print(clock_quality_factor.year, 10); | |
Serial.print(')'); | |
Serial.print(clock_quality.uses_summertime_quality, 10); | |
Serial.print(','); | |
Serial.print(clock_quality.timezone_change_scheduled_quality, 10); | |
Serial.print(','); | |
Serial.print(clock_quality.leap_second_scheduled_quality, 10); | |
Serial.print(','); | |
Serial.println(get_prediction_match(), 10); | |
} | |
void phase_lost_event_handler() { | |
DCF77_Second_Decoder::setup(); | |
DCF77_Minute_Decoder::setup(); | |
DCF77_Hour_Decoder::setup(); | |
DCF77_Day_Decoder::setup(); | |
DCF77_Weekday_Decoder::setup(); | |
DCF77_Month_Decoder::setup(); | |
DCF77_Year_Decoder::setup(); | |
} | |
void sync_achieved_event_handler() { | |
DCF77_Frequency_Control::qualify_calibration(); | |
} | |
void sync_lost_event_handler() { | |
DCF77_Frequency_Control::unqualify_calibration(); | |
bool reset_successors = (DCF77_Demodulator::get_quality_factor() == 0); | |
if (reset_successors) { | |
DCF77_Second_Decoder::setup(); | |
} | |
reset_successors |= (DCF77_Second_Decoder::get_quality_factor() == 0); | |
if (reset_successors) { | |
DCF77_Minute_Decoder::setup(); | |
} | |
reset_successors |= (DCF77_Minute_Decoder::get_quality_factor() == 0); | |
if (reset_successors) { | |
DCF77_Hour_Decoder::setup(); | |
} | |
reset_successors |= (DCF77_Hour_Decoder::get_quality_factor() == 0); | |
if (reset_successors) { | |
DCF77_Weekday_Decoder::setup(); | |
DCF77_Day_Decoder::setup(); | |
} | |
reset_successors |= (DCF77_Hour_Decoder::get_quality_factor() == 0); | |
if (reset_successors) { | |
DCF77_Month_Decoder::setup(); | |
} | |
reset_successors |= (DCF77_Month_Decoder::get_quality_factor() == 0); | |
if (reset_successors) { | |
DCF77_Year_Decoder::setup(); | |
} | |
} | |
void setup() { | |
DCF77_Demodulator::setup(); | |
phase_lost_event_handler(); | |
DCF77_Frequency_Control::setup(); | |
} | |
void process_single_tick_data(const DCF77::tick_t tick_data) { | |
using namespace DCF77; | |
using namespace DCF77_Second_Decoder; | |
using namespace DCF77_Minute_Decoder; | |
using namespace DCF77_Hour_Decoder; | |
using namespace DCF77_Weekday_Decoder; | |
using namespace DCF77_Day_Decoder; | |
using namespace DCF77_Month_Decoder; | |
using namespace DCF77_Year_Decoder; | |
using namespace DCF77_Flag_Decoder; | |
time_data_t now; | |
set_DCF77_encoder(now); | |
now.second += leap_second; | |
DCF77_Encoder::advance_second(now); | |
leap_second <<= 1; | |
leap_second += (now.second == 59 && DCF77_Encoder::get_current_signal(now) != sync_mark); | |
if (leap_second != 1) { | |
DCF77_Second_Decoder::process_single_tick_data(tick_data); | |
if (now.second == 0) { | |
DCF77_Minute_Decoder::advance_minute(); | |
if (now.minute.val == 0x00) { | |
while (get_hour().val <= 0x23 && get_hour().val != now.hour.val) { advance_hour(); } | |
if (now.hour.val == 0x00) { | |
if (get_weekday().val <= 0x07) { advance_weekday(); } | |
while (get_day().val <= 0x31 && get_day().val != now.day.val) { advance_day(); } | |
if (now.day.val == 0x01) { | |
if (get_month().val <= 0x12) { advance_month(); } | |
if (now.month.val == 0x01) { | |
if (now.year.val <= 0x99) { advance_year(); } | |
} | |
} | |
} | |
} | |
} | |
const uint8_t tick_value = (tick_data == long_tick || tick_data == undefined)? 1: 0; | |
DCF77_Flag_Decoder::process_tick(now.second, tick_value); | |
DCF77_Minute_Decoder::process_tick(now.second, tick_value); | |
DCF77_Hour_Decoder::process_tick(now.second, tick_value); | |
DCF77_Weekday_Decoder::process_tick(now.second, tick_value); | |
DCF77_Day_Decoder::process_tick(now.second, tick_value); | |
DCF77_Month_Decoder::process_tick(now.second, tick_value); | |
DCF77_Year_Decoder::process_tick(now.second, tick_value); | |
} | |
} | |
} | |
namespace DCF77_Demodulator { | |
using namespace DCF77; | |
const uint8_t bin_count = 100; | |
typedef struct { | |
uint16_t data[bin_count]; | |
uint8_t tick; | |
uint32_t noise_max; | |
uint32_t max; | |
uint8_t max_index; | |
} phase_bins; | |
phase_bins bins; | |
const uint16_t samples_per_second = 1000; | |
const uint16_t samples_per_bin = samples_per_second / bin_count; | |
const uint16_t bins_per_10ms = bin_count / 100; | |
const uint16_t bins_per_50ms = 5 * bins_per_10ms; | |
const uint16_t bins_per_60ms = 6 * bins_per_10ms; | |
const uint16_t bins_per_100ms = 10 * bins_per_10ms; | |
const uint16_t bins_per_200ms = 20 * bins_per_10ms; | |
const uint16_t bins_per_500ms = 50 * bins_per_10ms; | |
void setup() { | |
Hamming::setup(bins); | |
} | |
void decode_220ms(const uint8_t input, const uint8_t bins_to_go) { | |
static uint8_t count = 0; | |
static uint8_t decoded_data = 0; | |
count += input; | |
if (bins_to_go >= bins_per_100ms + bins_per_10ms) { | |
if (bins_to_go == bins_per_100ms + bins_per_10ms) { | |
decoded_data = count > bins_per_50ms? 2: 0; | |
count = 0; | |
} | |
} else { | |
if (bins_to_go == 0) { | |
decoded_data += count > bins_per_50ms? 1: 0; | |
count = 0; | |
DCF77_Clock_Controller::process_single_tick_data((DCF77::tick_t)decoded_data); | |
} | |
} | |
} | |
uint16_t wrap(const uint16_t value) { | |
uint16_t result = value; | |
while (result >= bin_count) { | |
result-= bin_count; | |
} | |
return result; | |
} | |
void phase_detection() { | |
uint32_t integral = 0; | |
for (uint16_t bin = 0; bin < bins_per_100ms; ++bin) { | |
integral += ((uint32_t)bins.data[bin])<<1; | |
} | |
for (uint16_t bin = bins_per_100ms; bin < bins_per_200ms; ++bin) { | |
integral += (uint32_t)bins.data[bin]; | |
} | |
bins.max = 0; | |
bins.max_index = 0; | |
for (uint16_t bin = 0; bin < bin_count; ++bin) { | |
if (integral > bins.max) { | |
bins.max = integral; | |
bins.max_index = bin; | |
} | |
integral -= (uint32_t)bins.data[bin]<<1; | |
integral += (uint32_t)(bins.data[wrap(bin + bins_per_100ms)] + | |
bins.data[wrap(bin + bins_per_200ms)]); | |
} | |
# 2577 "C:\\Documents and Settings\\STEFANOD\\Documenti\\Arduino\\libraries\\dcf77_library\\dcf77.cpp" | |
bins.noise_max = 0; | |
const uint16_t noise_index = wrap(bins.max_index + bins_per_200ms); | |
for (uint16_t bin = 0; bin < bins_per_100ms; ++bin) { | |
bins.noise_max += ((uint32_t)bins.data[wrap(noise_index + bin)])<<1; | |
} | |
for (uint16_t bin = bins_per_100ms; bin < bins_per_200ms; ++bin) { | |
bins.noise_max += (uint32_t)bins.data[wrap(noise_index + bin)]; | |
} | |
} | |
uint16_t N = 300; | |
void set_has_tuned_clock() { | |
N = 3600; | |
} | |
uint8_t phase_binning(const uint8_t input) { | |
Hamming::advance_tick(bins); | |
uint16_t& data = bins.data[bins.tick]; | |
if (data > N) { | |
data = N; | |
} | |
if (input) { | |
if (data < N) { | |
++data; | |
} | |
} else { | |
if (data > 0) { | |
--data; | |
} | |
} | |
return bins.tick; | |
} | |
void detector_stage_2(const uint8_t input) { | |
const uint8_t current_bin = bins.tick; | |
const uint8_t threshold = 30; | |
if (bins.max-bins.noise_max < threshold || | |
wrap(bin_count + current_bin - bins.max_index) == 53) { | |
phase_detection(); | |
} | |
static uint8_t bins_to_process = 0; | |
if (bins_to_process == 0) { | |
if (wrap((bin_count + current_bin - bins.max_index)) <= bins_per_100ms || | |
wrap((bin_count + bins.max_index - current_bin)) <= bins_per_10ms ) { | |
DCF77_Clock_Controller::flush(); | |
bins_to_process = bins_per_200ms + 2*bins_per_10ms; | |
} | |
} | |
if (bins_to_process > 0) { | |
--bins_to_process; | |
decode_220ms(input, bins_to_process); | |
} | |
} | |
void detector(const uint8_t sampled_data) { | |
static uint8_t current_sample = 0; | |
static uint8_t average = 0; | |
average += sampled_data; | |
if (++current_sample >= samples_per_bin) { | |
const uint8_t input = (average> samples_per_bin/2); | |
phase_binning(input); | |
detector_stage_2(input); | |
average = 0; | |
current_sample = 0; | |
} | |
} | |
void get_quality(uint32_t &lock_max, uint32_t &noise_max) { | |
const uint8_t prev_SREG = (*(volatile uint8_t *)((0x3F) + 0x20)); | |
__asm__ __volatile__ ("cli" ::: "memory"); | |
lock_max = bins.max; | |
noise_max = bins.noise_max; | |
(*(volatile uint8_t *)((0x3F) + 0x20)) = prev_SREG; | |
} | |
uint8_t get_quality_factor() { | |
const uint8_t prev_SREG = (*(volatile uint8_t *)((0x3F) + 0x20)); | |
__asm__ __volatile__ ("cli" ::: "memory"); | |
uint32_t delta = bins.max - bins.noise_max; | |
(*(volatile uint8_t *)((0x3F) + 0x20)) = prev_SREG; | |
uint8_t log2_plus_1 = 0; | |
uint32_t max = bins.max; | |
while (max) { | |
max >>= 1; | |
++log2_plus_1; | |
} | |
while (log2_plus_1) { | |
log2_plus_1 >>= 1; | |
delta >>= 1; | |
} | |
return delta<256? delta: 255; | |
}; | |
void debug() { | |
Serial.print((reinterpret_cast<const __FlashStringHelper *>((__extension__({static const char __c[] __attribute__((__progmem__)) = ("Phase: "); &__c[0];}))))); | |
Hamming::debug(bins); | |
} | |
void debug_verbose() { | |
debug(); | |
Serial.println((reinterpret_cast<const __FlashStringHelper *>((__extension__({static const char __c[] __attribute__((__progmem__)) = ("max_index, max, index, integral"); &__c[0];}))))); | |
uint32_t integral = 0; | |
for (uint16_t bin = 0; bin < bins_per_100ms; ++bin) { | |
integral += ((uint32_t)bins.data[bin])<<1; | |
} | |
for (uint16_t bin = bins_per_100ms; bin < bins_per_200ms; ++bin) { | |
integral += (uint32_t)bins.data[bin]; | |
} | |
uint32_t max = 0; | |
uint8_t max_index = 0; | |
for (uint16_t bin = 0; bin < bin_count; ++bin) { | |
if (integral > max) { | |
max = integral; | |
max_index = bin; | |
} | |
integral -= (uint32_t)bins.data[bin]<<1; | |
integral += (uint32_t)(bins.data[wrap(bin + bins_per_100ms)] + | |
bins.data[wrap(bin + bins_per_200ms)]); | |
Serial.print(max_index); | |
Serial.print((reinterpret_cast<const __FlashStringHelper *>((__extension__({static const char __c[] __attribute__((__progmem__)) = (", "); &__c[0];}))))); | |
Serial.print(max); | |
Serial.print((reinterpret_cast<const __FlashStringHelper *>((__extension__({static const char __c[] __attribute__((__progmem__)) = (", "); &__c[0];}))))); | |
Serial.print(bin); | |
Serial.print((reinterpret_cast<const __FlashStringHelper *>((__extension__({static const char __c[] __attribute__((__progmem__)) = (", "); &__c[0];}))))); | |
Serial.println(integral); | |
} | |
# 2756 "C:\\Documents and Settings\\STEFANOD\\Documenti\\Arduino\\libraries\\dcf77_library\\dcf77.cpp" | |
uint32_t noise_max = 0; | |
const uint16_t noise_index = wrap(max_index + bins_per_200ms); | |
for (uint16_t bin = 0; bin < bins_per_100ms; ++bin) { | |
noise_max += ((uint32_t)bins.data[wrap(noise_index + bin)])<<1; | |
} | |
for (uint16_t bin = bins_per_100ms; bin < bins_per_200ms; ++bin) { | |
noise_max += (uint32_t)bins.data[wrap(noise_index + bin)]; | |
} | |
Serial.print((reinterpret_cast<const __FlashStringHelper *>((__extension__({static const char __c[] __attribute__((__progmem__)) = ("noise_index, noise_max: "); &__c[0];}))))); | |
Serial.print(noise_index); | |
Serial.print((reinterpret_cast<const __FlashStringHelper *>((__extension__({static const char __c[] __attribute__((__progmem__)) = (", "); &__c[0];}))))); | |
Serial.println(noise_max); | |
} | |
} | |
namespace DCF77_Clock { | |
typedef void (*output_handler_t)(const time_t &decoded_time); | |
typedef uint8_t (*input_provider_t)(void); | |
void setup() { | |
DCF77_Clock_Controller::setup(); | |
} | |
void setup(const input_provider_t input_provider, const output_handler_t output_handler) { | |
DCF77_Clock_Controller::setup(); | |
DCF77_Clock_Controller::set_output_handler(output_handler); | |
DCF77_1_Khz_Generator::setup(input_provider); | |
}; | |
void debug() { | |
DCF77_Clock_Controller::debug(); | |
} | |
void set_input_provider(const input_provider_t input_provider) { | |
DCF77_1_Khz_Generator::setup(input_provider); | |
} | |
void set_output_handler(const output_handler_t output_handler) { | |
DCF77_Clock_Controller::set_output_handler(output_handler); | |
} | |
void auto_persist() { | |
DCF77_Clock_Controller::auto_persist(); | |
} | |
void convert_time(const DCF77::time_data_t ¤t_time, time_t &now) { | |
now.second = BCD::int_to_bcd(current_time.second); | |
now.minute = current_time.minute; | |
now.hour = current_time.hour; | |
now.weekday = current_time.weekday; | |
now.day = current_time.day; | |
now.month = current_time.month; | |
now.year = current_time.year; | |
now.uses_summertime = current_time.uses_summertime; | |
now.leap_second_scheduled = current_time.leap_second_scheduled; | |
now.timezone_change_scheduled = current_time.timezone_change_scheduled; | |
} | |
void get_current_time(time_t &now) { | |
DCF77::time_data_t current_time; | |
DCF77_Clock_Controller::get_current_time(current_time); | |
convert_time(current_time, now); | |
}; | |
void read_current_time(time_t &now) { | |
DCF77::time_data_t current_time; | |
DCF77_Clock_Controller::read_current_time(current_time); | |
convert_time(current_time, now); | |
}; | |
void print(time_t time) { | |
BCD::print(time.year); | |
Serial.print('-'); | |
BCD::print(time.month); | |
Serial.print('-'); | |
BCD::print(time.day); | |
Serial.print(' '); | |
Serial.print(time.weekday.val & 0xF, 16); | |
Serial.print(' '); | |
BCD::print(time.hour); | |
Serial.print(':'); | |
BCD::print(time.minute); | |
Serial.print(':'); | |
BCD::print(time.second); | |
if (time.uses_summertime) { | |
Serial.print((reinterpret_cast<const __FlashStringHelper *>((__extension__({static const char __c[] __attribute__((__progmem__)) = (" CEST "); &__c[0];}))))); | |
} else { | |
Serial.print((reinterpret_cast<const __FlashStringHelper *>((__extension__({static const char __c[] __attribute__((__progmem__)) = (" CET "); &__c[0];}))))); | |
} | |
Serial.print(time.timezone_change_scheduled? '*': '.'); | |
Serial.print(time.leap_second_scheduled ? 'L': '.'); | |
} | |
uint8_t get_overall_quality_factor() { | |
return DCF77_Clock_Controller::get_overall_quality_factor(); | |
}; | |
uint8_t get_clock_state() { | |
return DCF77_Clock_Controller::get_clock_state(); | |
}; | |
uint8_t get_prediction_match() { | |
return DCF77_Clock_Controller::get_prediction_match(); | |
}; | |
} | |
namespace DCF77_Frequency_Control { | |
volatile int8_t confirmed_precision = 0; | |
volatile boolean data_pending = false; | |
volatile uint16_t elapsed_minutes; | |
volatile uint16_t elapsed_centiseconds_mod_60000; | |
volatile uint8_t start_minute_mod_10; | |
const int8_t calibration_second = 5; | |
volatile calibration_state_t calibration_state = {false ,false}; | |
volatile int16_t deviation; | |
int8_t get_confirmed_precision() { | |
return confirmed_precision; | |
} | |
void qualify_calibration() { | |
calibration_state.qualified = true; | |
}; | |
void unqualify_calibration() { | |
calibration_state.qualified = false; | |
}; | |
int16_t compute_phase_deviation(uint8_t current_second, uint8_t current_minute_mod_10) { | |
int32_t deviation= | |
((int32_t) elapsed_centiseconds_mod_60000) - | |
((int32_t) current_second - (int32_t) calibration_second) * 100 - | |
((int32_t) current_minute_mod_10 - (int32_t) start_minute_mod_10) * 6000; | |
while (deviation > 30000) { deviation -= 60000; } | |
while (deviation <=-30000) { deviation += 60000; } | |
return deviation; | |
} | |
calibration_state_t get_calibration_state() { | |
return *(calibration_state_t *)&calibration_state; | |
} | |
int16_t get_current_deviation() { | |
return deviation; | |
} | |
void adjust() { | |
int16_t total_adjust = DCF77_1_Khz_Generator::read_adjustment(); | |
# 2944 "C:\\Documents and Settings\\STEFANOD\\Documenti\\Arduino\\libraries\\dcf77_library\\dcf77.cpp" | |
const int16_t frequency_offset = ((2667 * (int32_t)deviation) / elapsed_minutes); | |
confirmed_precision = (((2667 - 1) * 1) + elapsed_minutes) / elapsed_minutes; | |
if (confirmed_precision == 0) { confirmed_precision = 1; } | |
total_adjust -= frequency_offset; | |
if (total_adjust > max_total_adjust) { total_adjust = max_total_adjust; } | |
if (total_adjust < -max_total_adjust) { total_adjust = -max_total_adjust; } | |
DCF77_1_Khz_Generator::adjust(total_adjust); | |
} | |
void process_1_Hz_tick(const DCF77::time_data_t &decoded_time) { | |
const int16_t deviation_to_trigger_readjust = 5; | |
deviation = compute_phase_deviation(decoded_time.second, decoded_time.minute.digit.lo); | |
if (decoded_time.second == calibration_second) { | |
const bool leap_second_scheduled = decoded_time.leap_second_scheduled; | |
# 2972 "C:\\Documents and Settings\\STEFANOD\\Documenti\\Arduino\\libraries\\dcf77_library\\dcf77.cpp" | |
bool leap_second_scheduled_copy=((DCF77::time_data_t)decoded_time).leap_second_scheduled; | |
leap_second_scheduled_copy = true; | |
if (DCF77_Encoder::verify_leap_second_scheduled(decoded_time)) { | |
calibration_state.running = false; | |
} | |
leap_second_scheduled_copy = leap_second_scheduled; | |
if (calibration_state.running) { | |
if (calibration_state.qualified) { | |
if ((elapsed_minutes >= tau_min_minutes && ((deviation)>0?(deviation):-(deviation)) >= deviation_to_trigger_readjust) || | |
elapsed_minutes >= tau_max_minutes) { | |
adjust(); | |
data_pending = true; | |
calibration_state.running = false; | |
} | |
} else { | |
if (elapsed_minutes >= tau_max_minutes) { | |
calibration_state.running = false; | |
} | |
} | |
} else { | |
if (calibration_state.qualified) { | |
elapsed_centiseconds_mod_60000 = 0; | |
elapsed_minutes = 0; | |
start_minute_mod_10 = decoded_time.minute.digit.lo; | |
calibration_state.running = true; | |
} | |
} | |
} | |
} | |
void process_1_kHz_tick() { | |
static uint8_t divider = 0; | |
if (divider < 9) { | |
++divider; | |
} else { | |
divider = 0; | |
if (elapsed_centiseconds_mod_60000 < 59999) { | |
++elapsed_centiseconds_mod_60000; | |
} else { | |
elapsed_centiseconds_mod_60000 = 0; | |
} | |
if (elapsed_centiseconds_mod_60000 % 6000 == 0) { | |
++elapsed_minutes; | |
} | |
} | |
} | |
const char ID_u = 'u'; | |
const char ID_k = 'k'; | |
void persist_to_eeprom(const int8_t precision, const int16_t adjust) { | |
uint16_t eeprom = eeprom_base; | |
__eewr_byte_m2560((uint8_t *)(eeprom++), ID_u); | |
__eewr_byte_m2560((uint8_t *)(eeprom++), ID_k); | |
__eewr_byte_m2560((uint8_t *)(eeprom++), (uint8_t) precision); | |
__eewr_byte_m2560((uint8_t *)(eeprom++), (uint8_t) precision); | |
__eewr_word_m2560((uint16_t *)eeprom, (uint16_t) adjust); | |
eeprom += 2; | |
__eewr_word_m2560((uint16_t *)eeprom, (uint16_t) adjust); | |
} | |
void read_from_eeprom(int8_t &precision, int16_t &adjust) { | |
uint16_t eeprom = eeprom_base; | |
if (__eerd_byte_m2560((const uint8_t *)(eeprom++)) == ID_u && | |
__eerd_byte_m2560((const uint8_t *)(eeprom++)) == ID_k) { | |
uint8_t ee_precision = __eerd_byte_m2560((const uint8_t *)(eeprom++)); | |
if (ee_precision == __eerd_byte_m2560((const uint8_t *)(eeprom++))) { | |
const uint16_t ee_adjust = __eerd_word_m2560((const uint16_t *)eeprom); | |
eeprom += 2; | |
if (ee_adjust == __eerd_word_m2560((const uint16_t *)eeprom)) { | |
precision = (int8_t) ee_precision; | |
adjust = (int16_t) ee_adjust; | |
return; | |
} | |
} | |
} | |
precision = 0; | |
adjust = 0; | |
} | |
void auto_persist() { | |
int16_t adjust; | |
int8_t precision; | |
const uint8_t prev_SREG = (*(volatile uint8_t *)((0x3F) + 0x20)); | |
__asm__ __volatile__ ("cli" ::: "memory"); | |
if (data_pending && confirmed_precision > 0) { | |
precision = confirmed_precision; | |
adjust = DCF77_1_Khz_Generator::read_adjustment(); | |
} else { | |
data_pending = false; | |
} | |
(*(volatile uint8_t *)((0x3F) + 0x20)) = prev_SREG; | |
if (data_pending) { | |
int16_t ee_adjust; | |
int8_t ee_precision; | |
read_from_eeprom(ee_precision, ee_adjust); | |
if (confirmed_precision < ((ee_precision)>0?(ee_precision):-(ee_precision)) || | |
( ((ee_precision)>0?(ee_precision):-(ee_precision)) < 8 && | |
((ee_adjust-adjust)>0?(ee_adjust-adjust):-(ee_adjust-adjust)) > 8 ) || | |
( confirmed_precision == 1 && | |
((ee_adjust-adjust)>0?(ee_adjust-adjust):-(ee_adjust-adjust)) > 0 ) ) | |
{ | |
__asm__ __volatile__ ("cli" ::: "memory"); | |
const int16_t new_ee_adjust = adjust; | |
const int8_t new_ee_precision = precision; | |
(*(volatile uint8_t *)((0x3F) + 0x20)) = prev_SREG; | |
persist_to_eeprom(new_ee_precision, new_ee_adjust); | |
DCF77_Clock_Controller::on_tuned_clock(); | |
} | |
data_pending = false; | |
} | |
} | |
void setup() { | |
int16_t adjust; | |
int8_t ee_precision; | |
read_from_eeprom(ee_precision, adjust); | |
if (ee_precision) { | |
DCF77_Clock_Controller::on_tuned_clock(); | |
} | |
const uint8_t prev_SREG = (*(volatile uint8_t *)((0x3F) + 0x20)); | |
__asm__ __volatile__ ("cli" ::: "memory"); | |
(*(volatile uint8_t *)((0x3F) + 0x20)) = prev_SREG; | |
DCF77_1_Khz_Generator::adjust(adjust); | |
} | |
void debug() { | |
Serial.println((reinterpret_cast<const __FlashStringHelper *>((__extension__({static const char __c[] __attribute__((__progmem__)) = ("confirmed_precision ?? adjustment, deviation, elapsed"); &__c[0];}))))); | |
Serial.print(confirmed_precision); | |
Serial.print((reinterpret_cast<const __FlashStringHelper *>((__extension__({static const char __c[] __attribute__((__progmem__)) = (" Hz "); &__c[0];}))))); | |
Serial.print(calibration_state.running? '@': '.'); | |
Serial.print(calibration_state.qualified? '+': '-'); | |
Serial.print(' '); | |
Serial.print((reinterpret_cast<const __FlashStringHelper *>((__extension__({static const char __c[] __attribute__((__progmem__)) = (", "); &__c[0];}))))); | |
Serial.print(DCF77_1_Khz_Generator::read_adjustment()); | |
Serial.print((reinterpret_cast<const __FlashStringHelper *>((__extension__({static const char __c[] __attribute__((__progmem__)) = (" Hz, "); &__c[0];}))))); | |
Serial.print(deviation); | |
Serial.print((reinterpret_cast<const __FlashStringHelper *>((__extension__({static const char __c[] __attribute__((__progmem__)) = (" ticks, "); &__c[0];}))))); | |
Serial.print(elapsed_minutes); | |
Serial.print((reinterpret_cast<const __FlashStringHelper *>((__extension__({static const char __c[] __attribute__((__progmem__)) = (" min, "); &__c[0];}))))); | |
Serial.print(elapsed_centiseconds_mod_60000); | |
Serial.println((reinterpret_cast<const __FlashStringHelper *>((__extension__({static const char __c[] __attribute__((__progmem__)) = (" cs mod 60000"); &__c[0];}))))); | |
} | |
} | |
namespace DCF77_1_Khz_Generator { | |
uint8_t zero_provider() { | |
return 0; | |
} | |
static DCF77_Clock::input_provider_t the_input_provider = zero_provider; | |
static int16_t adjust_pp16m = 0; | |
static int32_t cumulated_phase_deviation = 0; | |
void adjust(const int16_t pp16m) { | |
const uint8_t prev_SREG = (*(volatile uint8_t *)((0x3F) + 0x20)); | |
__asm__ __volatile__ ("cli" ::: "memory"); | |
adjust_pp16m = pp16m; | |
(*(volatile uint8_t *)((0x3F) + 0x20)) = prev_SREG; | |
} | |
int16_t read_adjustment() { | |
const uint8_t prev_SREG = (*(volatile uint8_t *)((0x3F) + 0x20)); | |
__asm__ __volatile__ ("cli" ::: "memory"); | |
const int16_t pp16m = adjust_pp16m; | |
(*(volatile uint8_t *)((0x3F) + 0x20)) = prev_SREG; | |
return pp16m; | |
} | |
void init_timer_2() { | |
(*(volatile uint8_t *)(0xB1)) = (0<<3) | (1<<2); | |
(*(volatile uint8_t *)(0xB0)) = (1<<1) | (0<<0); | |
(*(volatile uint8_t *)(0xB3)) = 249; | |
(*(volatile uint8_t *)(0x70)) = (1<<1); | |
} | |
void stop_timer_0() { | |
(*(volatile uint8_t *)(0x6E)) = 0; | |
} | |
void setup(const DCF77_Clock::input_provider_t input_provider) { | |
init_timer_2(); | |
stop_timer_0(); | |
the_input_provider = input_provider; | |
} | |
void isr_handler() { | |
cumulated_phase_deviation += adjust_pp16m; | |
if (cumulated_phase_deviation >= 64000) { | |
cumulated_phase_deviation -= 64000; | |
(*(volatile uint8_t *)(0xB3)) = 248; | |
} else | |
if (cumulated_phase_deviation <= -64000) { | |
cumulated_phase_deviation += 64000; | |
(*(volatile uint8_t *)(0xB3)) = 250; | |
} else { | |
(*(volatile uint8_t *)(0xB3)) = 249; | |
} | |
DCF77_Clock_Controller::process_1_kHz_tick_data(the_input_provider()); | |
} | |
} | |
extern "C" void __vector_13 (void) __attribute__ ((signal,used, externally_visible)) ; void __vector_13 (void) { | |
DCF77_1_Khz_Generator::isr_handler(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment