#include "project.h" #define J2(a,b) a ## b #define J3(a,b,c) a ## b ## c #define P1 (GPIO4) #define P1_PORT GPIOE #define T_BIT 2 #define T_PORT GPIOE #define T_EXTI_LINE T_BIT #define M_T(a) J2(GPIO,a) #define T M_T(T_BIT) #define M_EXTI_T(a) J2(EXTI,a) #define EXTI_T M_EXTI_T(T_EXTI_LINE) #define M_exti_t_isr(a) J3(exti,a,_isr) #define exti_t_isr M_exti_t_isr(T_EXTI_LINE) #define M_NVIC_EXTI_T_IRQ(a) J3(NVIC_EXTI,a,_IRQ) #define NVIC_EXTI_T_IRQ M_NVIC_EXTI_T_IRQ(T_EXTI_LINE) static Event_ring dcf77_ring; static EPOCH dcf77_time; static uint64_t dcf77_last_second; uint64_t dcf77_last_happy; static char dcf77_info[40]; void exti_t_isr (void) { uint32_t now = HW_CLOCK_REG; int v; v = !!gpio_get (T_PORT, T); nvic_disable_irq (NVIC_EXTI_T_IRQ); exti_reset_request (EXTI_T); dcf77_ring.events[dcf77_ring.tx_ptr].when = now; dcf77_ring.events[dcf77_ring.tx_ptr].ptp = ptp_get(); dcf77_ring.events[dcf77_ring.tx_ptr].value = v; dcf77_ring.tx_ptr = (dcf77_ring.tx_ptr + 1) & ERING_MASK; nvic_enable_irq (NVIC_EXTI_T_IRQ); } static uint8_t bits[60]; static void process_bits (uint64_t abs, uint64_t ptp) { UTC u; EPOCH e; 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; e = time_utc_to_epoch (u); e.s -= 3600; /*CET*/ if (bits[17]) e.s -= 3600; /*CEST*/ e.s -= 2; /*Message arrives 2s early*/ dcf77_time = e; dcf77_last_happy = make_happy (abs, 60); pll_set_offset (e, abs, ptp); 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: ", e, dcf77_info); meteotime_save (&u, bits); dump_bits ("dcf77", bits); } static void report_bit (uint64_t abs, uint64_t ptp, 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, ptp); } 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; uint64_t ptp; int v; led2_set (!!gpio_get (T_PORT, T)); 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; ptp = dcf77_ring.events[dcf77_ring.rx_ptr].ptp; //led2_set(v); dcf77_ring.rx_ptr = (dcf77_ring.rx_ptr + 1) & ERING_MASK; if (v) { pulse_w = now - last_0; pulse_w /= (HW_CLOCK_HZ / 1000); last_1 = now; if (pulse_w > 300) { last_s = now; is_s = 1; second++; dcf77_time.s++; } if (pulse_w > 1300) { had_m = 1; second = 0; } } else { pulse_w = now - last_1; pulse_w /= (HW_CLOCK_HZ / 1000); if (pulse_w > 150) bit = 1; else bit = 0; sprintf (dcf77_info, "m=%d s=%02d b=%d", had_m, second, bit); if (had_m) report_bit (abs, ptp, second, bit); last_0 = now; } offset = now - last_s; offset /= (HW_CLOCK_HZ / 1000); if (is_s) { abs = ref_extend (now); dcf77_last_second = abs; pll_dispatch (dcf77_last_happy, abs, ptp, "DCF77"); report_time ("DCF", dcf77_time, abs, dcf77_info); } } void dcf77_init (void) { MAP_INPUT (T); MAP_OUTPUT_PP (P1); gpio_set (P1_PORT, P1); delay_ms (50); gpio_clear (P1_PORT, P1); exti_select_source (EXTI_T, T_PORT); exti_set_trigger (EXTI_T, EXTI_TRIGGER_BOTH); exti_enable_request (EXTI_T); nvic_enable_irq (NVIC_EXTI_T_IRQ); }