From 25e6afd831b94b9735cc6691ee19c8edc921aca7 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 8 Apr 2018 01:14:30 +0100 Subject: working decoding --- app/msf.c | 226 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 226 insertions(+) create mode 100644 app/msf.c (limited to 'app/msf.c') diff --git a/app/msf.c b/app/msf.c new file mode 100644 index 0000000..392bfe7 --- /dev/null +++ b/app/msf.c @@ -0,0 +1,226 @@ +#include "project.h" + +#define P1 (GPIO1) +#define P1_PORT GPIOB + +#define T (GPIO0) +#define T_PORT GPIOB + +static uint8_t bitsa[60], bitsb[60]; + +static int time_known; +static int check_parity (uint8_t *d, unsigned s, unsigned e, uint8_t p) +{ + unsigned i; + + for (i = s; i <= e; ++i) + p ^= d[i]; + + return !p; +} + + +static unsigned bcd (uint8_t *d, unsigned s, unsigned e) +{ + unsigned ret = 0, c, b, i; + + for (i = e, c = 1, b = 0; i >= s; --i, b++) { + + if (d[i]) ret += c; + + + switch (b & 3) { + case 0: + case 1: + case 2: + c <<= 1; + break; + + default: + c >>= 3; + c *= 10; + } + } + + return ret; +} + + + +static int check_min_ident (uint8_t *i) +{ + if (i[0]) return 1; + + if (!i[1]) return 1; + + if (!i[2]) return 1; + + if (!i[3]) return 1; + + if (!i[4]) return 1; + + if (!i[5]) return 1; + + if (!i[6]) return 1; + + if (i[7]) return 1; + + return 0; +} + + + +static void process_bits (uint64_t abs) +{ + UTC u; + EPOCH msf_time; + + + if (check_min_ident (&bitsa[52])) return; + + if (check_parity (bitsa, 17, 24, bitsb[54])) return; + + if (check_parity (bitsa, 25, 35, bitsb[55])) return; + + if (check_parity (bitsa, 36, 38, bitsb[56])) return; + + if (check_parity (bitsa, 39, 51, bitsb[57])) return; + + u.jday = 0; + u.year = bcd (bitsa, 17, 24); + u.month = bcd (bitsa, 25, 29); + u.mday = bcd (bitsa, 30, 35); + u.hour = bcd (bitsa, 39, 44); + u.minute = bcd (bitsa, 45, 51); + u.second = 59; + u.nanosecond = 0; + + /* This is always valid a check_min_ident will fail for leap seconds*/ + + msf_time = time_utc_to_epoch (u); + msf_time.s -= 59; + + pll_set_offset (msf_time, abs); + time_known = 1; + + printf ("Next minute is: %02d-%02d-%02d %02d:%02d\r\n", u.year, u.month, u.mday, u.hour, u.minute); + time_print_epoch (msf_time); +} + + +static void report_bits (uint64_t abs, int second, int a, int b) +{ + if ((!second) || (second > 59)) return; + + bitsa[second] = a; + bitsb[second] = b; + + if (second == 59) process_bits (abs); + +} + +static void report_time (uint64_t abs) +{ + EPOCH e = pll_decompose (abs); + time_print_epoch (e); + printf ("%d\r\n", (unsigned) e.s); +} + +void exti0_isr (void) +{ + static uint32_t last_0; + static uint32_t last_1; + static uint32_t last_s; + static int second, bita, bitb, had_m; + + uint32_t now = SCS_DWT_CYCCNT; + uint64_t abs; + + uint32_t pulse_w, offset; + int is_s = 0; + int v; + + nvic_disable_irq (NVIC_EXTI0_IRQ); + exti_reset_request (EXTI0); + + v = !!gpio_get (T_PORT, T); + + if (v) { + pulse_w = now - last_0; + pulse_w /= (HZ / 1000); + + if (pulse_w > 300) { + last_s = now; + is_s = 1; + } + + last_1 = now; + + } else { + pulse_w = now - last_1; + pulse_w /= (HZ / 1000); + + if (pulse_w > 400) { + had_m = 1; + second = 0; + } + + last_0 = now; + } + + offset = now - last_s; + offset /= (HZ / 1000); + + + if (is_s) { + abs = abs_extend (now); + pll_dispatch (abs); + + if (had_m) { + report_bits (abs, second, bita, bitb); + second++; + + } + + if (time_known) + report_time (abs); + } + + + + if (!v) { /* 1->0 transition */ + if (offset < 150) { + bita = 0; + bitb = 0; + } + + if (offset < 250) + bitb = 0; + } else { /* 0->1 transition*/ + if (is_s) { + bita = 1; + bitb = 1; + } else if (offset < 250) + bitb = 1; + } + + + + nvic_enable_irq (NVIC_EXTI0_IRQ); +} + +void +radio_init (void) +{ + MAP_INPUT (T); + MAP_OUTPUT_PP (P1); + + gpio_clear (P1_PORT, P1); + + exti_select_source (EXTI0, T_PORT); + exti_set_trigger (EXTI0, EXTI_TRIGGER_BOTH); + exti_enable_request (EXTI0); + nvic_enable_irq (NVIC_EXTI0_IRQ); +} + + -- cgit v1.2.3