diff options
Diffstat (limited to 'app/dcf77.c')
-rw-r--r-- | app/dcf77.c | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/app/dcf77.c b/app/dcf77.c new file mode 100644 index 0000000..edc152b --- /dev/null +++ b/app/dcf77.c @@ -0,0 +1,186 @@ +#include "project.h" + +#define P1 (GPIO11) +#define P1_PORT GPIOD + +#define T (GPIO12) +#define T_PORT GPIOD + + +static Event_ring dcf77_ring; + + +uint64_t dcf77_last_second; + +void exti15_10_isr (void) +{ + uint32_t now = SCS_DWT_CYCCNT; + int v; + + v = !!gpio_get (T_PORT, T); + + nvic_disable_irq (NVIC_EXTI15_10_IRQ); + exti_reset_request (EXTI12); + + dcf77_ring.events[dcf77_ring.tx_ptr].when = now; + dcf77_ring.events[dcf77_ring.tx_ptr].value = v; + dcf77_ring.tx_ptr = (dcf77_ring.tx_ptr + 1) & ERING_MASK; + + nvic_enable_irq (NVIC_EXTI15_10_IRQ); +} + + + + +static uint8_t bits[60]; + +static int time_known; + +static void process_bits (uint64_t abs) +{ + UTC u; + EPOCH dcf77_time; + + + if (bits[0]) return; + + if (!bits[20]) return; + + if (!check_parity (bits, 21, 27, bits[28])) return; + + if (!check_parity (bits, 29, 34, bits[35])) return; + + if (!check_parity (bits, 36, 57, bits[58])) return; + + u.jday = 0; + u.year = le_bcd (bits, 50, 57); + u.month = le_bcd (bits, 45, 49); + u.mday = bcd (bits, 36, 41); + u.hour = bcd (bits, 29, 34); + u.minute = bcd (bits, 21, 27); + u.second = 58; + u.nanosecond = 0; + + + dcf77_time = time_utc_to_epoch (u); + dcf77_time.s -= 58; + +#if 0 + pll_set_offset (dcf77_time, abs); +#endif + time_known = 1; + + printf ("DCF77: Next minute is: %02d-%02d-%02d %02d:%02d\r\n", u.year, u.month, u.mday, u.hour, u.minute); + time_print_epoch ("DCF77: ", dcf77_time); + + dump_bits("dcf77",bits); +} + + +static void report_bit (uint64_t abs, int second, int b) +{ + if ((second < 0) || (second > 58)) return; + + bits[second] = b; + + // printf("DCF77: bits[%d]=%d\r\n",second,b); + + if (second == 58) process_bits (abs); + +} + +static void report_time (uint64_t abs) +{ +#if 0 + EPOCH e = pll_decompose (abs); + time_print_epoch ("DCF77: ", e); +#endif +} + + +void dcf77_dispatch (void) +{ + static uint32_t last_0, last_1, last_s; + static int second, bit, had_m; + uint32_t pulse_w, offset; + static uint64_t abs; + int is_s = 0; + + uint32_t now; + int v; + + + + + if (dcf77_ring.rx_ptr == dcf77_ring.tx_ptr) return; + + v = dcf77_ring.events[dcf77_ring.rx_ptr].value; + now = dcf77_ring.events[dcf77_ring.rx_ptr].when; + + dcf77_ring.rx_ptr = (dcf77_ring.rx_ptr + 1) & ERING_MASK; + + if (v) { + pulse_w = now - last_0; + pulse_w /= (HZ / 1000); + + last_1 = now; + + if (pulse_w > 300) { + last_s = now; + is_s = 1; + second++; + } + + if (pulse_w > 1300) { + had_m = 1; + second = 0; + } + + } else { + pulse_w = now - last_1; + pulse_w /= (HZ / 1000); + + if (pulse_w > 150) + bit = 1; + else + bit = 0; + + if (had_m) + report_bit (abs, second, bit); + + last_0 = now; + } + + offset = now - last_s; + offset /= (HZ / 1000); + + if (is_s) { + abs = abs_extend (now); + dcf77_last_second = abs; + + //pll_dispatch (abs); + + if (time_known) + report_time (abs); + } + + +} + + + +void +dcf77_init (void) +{ + MAP_INPUT (T); + MAP_OUTPUT_PP (P1); + + gpio_clear (P1_PORT, P1); + + exti_select_source (EXTI12, T_PORT); + exti_set_trigger (EXTI12, EXTI_TRIGGER_BOTH); + exti_enable_request (EXTI12); + nvic_enable_irq (NVIC_EXTI15_10_IRQ); +} + + |