summaryrefslogtreecommitdiffstats
path: root/app/dcf77.c
diff options
context:
space:
mode:
Diffstat (limited to 'app/dcf77.c')
-rw-r--r--app/dcf77.c186
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);
+}
+
+