#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 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 = le_bcd (bits, 36, 41); u.hour = le_bcd (bits, 29, 34); u.minute = le_bcd (bits, 21, 27); u.second = 0; u.nanosecond = 0; dcf77_time = time_utc_to_epoch (u); dcf77_time.s -= 2; /*Message arrives 2s early*/ dcf77_time.s -= 3600; /*CET*/ if (bits[17]) dcf77_time.s -= 3600; /*CEST*/ pll_set_offset (dcf77_time, abs); 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 1 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); }