From 6cab91b0ab0b538cd63d94c1afd38e3fd287efec Mon Sep 17 00:00:00 2001 From: root Date: Tue, 17 Apr 2018 10:35:31 +0100 Subject: happy dcf77 better pll, and stamps for long term stability --- app/Makefile | 2 +- app/main.c | 17 +++++++---- app/msf.c | 87 ++++++++++++++++++++++++++++---------------------------- app/pll.c | 82 ++++++++++++++++++++++++++++++++++------------------ app/project.h | 4 ++- app/prototypes.h | 26 +++++++++++++++-- app/steth.c | 7 ++++- app/time_fn.c | 8 +++--- app/time_fn.h | 4 +-- 9 files changed, 148 insertions(+), 89 deletions(-) diff --git a/app/Makefile b/app/Makefile index 0d8d19d..e5d6731 100644 --- a/app/Makefile +++ b/app/Makefile @@ -25,7 +25,7 @@ PROG=msf V=1 default: ${PROG}.elf -CSRCS=led.c ticker.c ring.c usart.c stdio.c lwip_glue.c steth.c msf.c abs.c pll.c main.c time_fn.c ntp.c +CSRCS=led.c ticker.c ring.c usart.c stdio.c lwip_glue.c steth.c msf.c abs.c pll.c main.c time_fn.c ntp.c dcf77.c util.c stats.c HSRCS=project.h ring.h pins.h LWIP=lwip/lwip-1.4.1 diff --git a/app/main.c b/app/main.c index 2f25fb6..48828c8 100644 --- a/app/main.c +++ b/app/main.c @@ -12,10 +12,11 @@ board_setup (void) rcc_periph_clock_enable (RCC_GPIOD); rcc_periph_clock_enable (RCC_USART6); - nvic_set_priority (NVIC_USART6_IRQ, 0xff); - nvic_set_priority (NVIC_EXTI0_IRQ, 0x80); - nvic_set_priority (NVIC_ETH_IRQ, 0x40); - nvic_set_priority (NVIC_SYSTICK_IRQ, 0x40); + nvic_set_priority (NVIC_EXTI0_IRQ, 0); + nvic_set_priority (NVIC_EXTI15_10_IRQ, 1); + nvic_set_priority (NVIC_USART6_IRQ, 2); + nvic_set_priority (NVIC_ETH_IRQ, 3); + nvic_set_priority (NVIC_SYSTICK_IRQ, 4) ; } @@ -28,7 +29,8 @@ system_init (void) ticker_init(); usart_init(); - radio_init(); + msf_init(); + dcf77_init(); start_lwip(); steth_init(); @@ -42,10 +44,13 @@ main (void) system_init(); - printf ("Fish\r\n"); + printf ("Boot\r\n"); while (1) { + msf_dispatch(); + dcf77_dispatch(); + dispatch_lwip(); steth_dispatch(); diff --git a/app/msf.c b/app/msf.c index 392bfe7..2e7dd93 100644 --- a/app/msf.c +++ b/app/msf.c @@ -6,44 +6,35 @@ #define T (GPIO0) #define T_PORT GPIOB -static uint8_t bitsa[60], bitsb[60]; +static Event_ring msf_ring; -static int time_known; -static int check_parity (uint8_t *d, unsigned s, unsigned e, uint8_t p) +uint64_t msf_last_second; + + +void exti0_isr (void) { - unsigned i; + uint32_t now = SCS_DWT_CYCCNT; + int v; - for (i = s; i <= e; ++i) - p ^= d[i]; + v = !!gpio_get (T_PORT, T); - return !p; -} + nvic_disable_irq (NVIC_EXTI0_IRQ); + exti_reset_request (EXTI0); + msf_ring.events[msf_ring.tx_ptr].when = now; + msf_ring.events[msf_ring.tx_ptr].value = v; + msf_ring.tx_ptr = (msf_ring.tx_ptr + 1) & ERING_MASK; -static unsigned bcd (uint8_t *d, unsigned s, unsigned e) -{ - unsigned ret = 0, c, b, i; + nvic_enable_irq (NVIC_EXTI0_IRQ); - 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; - } - } +static uint8_t bitsa[60], bitsb[60]; - return ret; -} +static int time_known; @@ -103,8 +94,10 @@ static void process_bits (uint64_t abs) 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); + stats_stamp (u, abs); + + printf ("MSF: 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); } @@ -121,29 +114,31 @@ static void report_bits (uint64_t abs, int second, int a, int b) static void report_time (uint64_t abs) { +#if 0 EPOCH e = pll_decompose (abs); - time_print_epoch (e); - printf ("%d\r\n", (unsigned) e.s); + time_print_epoch ("MSF: ", e); +#endif } -void exti0_isr (void) + +void msf_dispatch (void) { - static uint32_t last_0; - static uint32_t last_1; - static uint32_t last_s; + static uint32_t last_0, last_1, last_s; static int second, bita, bitb, had_m; - - uint32_t now = SCS_DWT_CYCCNT; - uint64_t abs; - uint32_t pulse_w, offset; + uint64_t abs; int is_s = 0; + + uint32_t now; int v; - nvic_disable_irq (NVIC_EXTI0_IRQ); - exti_reset_request (EXTI0); - v = !!gpio_get (T_PORT, T); + if (msf_ring.rx_ptr == msf_ring.tx_ptr) return; + + v = msf_ring.events[msf_ring.rx_ptr].value; + now = msf_ring.events[msf_ring.rx_ptr].when; + + msf_ring.rx_ptr = (msf_ring.rx_ptr + 1) & ERING_MASK; if (v) { pulse_w = now - last_0; @@ -174,16 +169,21 @@ void exti0_isr (void) if (is_s) { abs = abs_extend (now); + msf_last_second = abs; + pll_dispatch (abs); + + if (had_m) { report_bits (abs, second, bita, bitb); second++; - } if (time_known) report_time (abs); + + stats(); } @@ -206,11 +206,10 @@ void exti0_isr (void) - nvic_enable_irq (NVIC_EXTI0_IRQ); } void -radio_init (void) +msf_init (void) { MAP_INPUT (T); MAP_OUTPUT_PP (P1); diff --git a/app/pll.c b/app/pll.c index 4b89143..03d214c 100644 --- a/app/pll.c +++ b/app/pll.c @@ -2,12 +2,13 @@ #define JUMP_THRESH 0.1 #define JUMP_TICKS 30 -#define FEEDBACK 0.001 +#define FEEDBACK 0.000001 +#define WARM_UP 30 static int64_t offset; static int64_t phase; -static int64_t freq = HZ; +int64_t pll_freq = HZ; static int out_of_lock = JUMP_TICKS + 1; @@ -15,23 +16,26 @@ uint64_t pll_last_update; int pll_valid = 0; +static int warming_up = WARM_UP; -static void modify_freq (uint64_t now, int d) + + +static void modify_pll_freq (uint64_t now, int d) { int64_t pd1, pd2, te; pd1 = now - phase; - te = pd1 / freq; - pd1 %= freq; + te = pd1 / pll_freq; + pd1 %= pll_freq; if (d > 0) - freq += d; + pll_freq += d; else - freq -= -d; + pll_freq -= -d; - pd2 = pd1 + (te * freq); + pd2 = pd1 + (te * pll_freq); phase = now - pd2; } @@ -41,44 +45,49 @@ void pll_dispatch (uint64_t edge) double f; int64_t pd; + if (warming_up) { + warming_up--; + return; + } + { int diff, hf; pd = edge - phase; - pd %= freq; + pd %= pll_freq; - hf = (int) (freq >> 1); + hf = (int) (pll_freq >> 1); diff = (int) pd; if (diff > hf) - diff = diff - (int) freq; + diff = diff - (int) pll_freq; f = (double) diff; - f /= (double) freq; + f /= (double) pll_freq; } if ((f > (JUMP_THRESH)) || (f < - (JUMP_THRESH))) out_of_lock++; - else + else if (out_of_lock <= JUMP_TICKS) out_of_lock = 0; #if 0 - printf ("PLL pd %.3f freq %d phase %d\r\n", (float) f, (int) freq, (int) phase); + printf ("PLL pd %.3f pll_freq %d phase %d\r\n", (float) f, (int) pll_freq, (int) phase); #endif if (out_of_lock > JUMP_TICKS) { phase += pd; out_of_lock = 0; printf ("PLL - jumping\r\n"); - freq = HZ; + pll_freq = HZ; } else { f *= FEEDBACK; - f *= (double) freq; + f *= (double) pll_freq; - modify_freq (edge, (int) f); + modify_pll_freq (edge, (int) f); } @@ -90,9 +99,9 @@ void pll_dispatch (uint64_t edge) void pll_set_offset (EPOCH epoch, uint64_t abs) { /* Find nearest second to abs*/ - abs += freq >> 2; + abs += pll_freq >> 2; abs -= phase; - abs /= freq; + abs /= pll_freq; offset = epoch.s - abs; @@ -101,23 +110,42 @@ void pll_set_offset (EPOCH epoch, uint64_t abs) - -EPOCH pll_decompose (uint64_t abs) +EPOCH _pll_decompose (uint64_t abs) { EPOCH ret; - abs -= phase; - - ret.s = abs / freq; - abs -= freq * ret.s; - + ret.s = abs / pll_freq; + abs -= pll_freq * ret.s; ret.s += offset; abs *= (uint64_t) 1000000000; - abs = abs / freq; + abs = abs / pll_freq; ret.ns = abs; return ret; } + +EPOCH pll_decompose_diff (int64_t diff) +{ + EPOCH ret; + + if (diff >= 0) + return _pll_decompose (diff); + + ret = _pll_decompose (-diff); + ret.s = -ret.s; + ret.ns = -ret.ns; + + return ret; +} + + +EPOCH pll_decompose (uint64_t abs) +{ + + abs -= phase; + + return _pll_decompose (abs); +} diff --git a/app/project.h b/app/project.h index 4fc679a..013ceea 100644 --- a/app/project.h +++ b/app/project.h @@ -34,10 +34,12 @@ #include "pins.h" +#include "events.h" #include "ring.h" #include "prototypes.h" -#define HZ 168000000 +//#define HZ 168000000 +#define HZ 167968615 #define TRACE do { stdio_drain(); printf("%s:%d\r\n",__FUNCTION__,__LINE__); } while (0) diff --git a/app/prototypes.h b/app/prototypes.h index 279a182..8675022 100644 --- a/app/prototypes.h +++ b/app/prototypes.h @@ -45,20 +45,40 @@ extern err_t steth_lwip_init(struct netif *netif); extern void steth_init(void); extern void steth_dispatch(void); /* msf.c */ +extern uint64_t msf_last_second; extern void exti0_isr(void); -extern void radio_init(void); +extern void msf_dispatch(void); +extern void msf_init(void); /* abs.c */ extern uint64_t abs_extend(uint32_t now); extern uint64_t abs_get(void); extern void abs_slow_tick(void); /* pll.c */ +extern int64_t pll_freq; +extern uint64_t pll_last_update; +extern int pll_valid; extern void pll_dispatch(uint64_t edge); extern void pll_set_offset(EPOCH epoch, uint64_t abs); +extern EPOCH _pll_decompose(uint64_t abs); +extern EPOCH pll_decompose_diff(int64_t diff); extern EPOCH pll_decompose(uint64_t abs); /* main.c */ extern int main(void); /* time_fn.c */ extern UTC time_epoch_to_utc(EPOCH epoch); extern EPOCH time_utc_to_epoch(UTC u); -extern void time_print_utc(UTC u); -extern void time_print_epoch(EPOCH e); +extern void time_print_utc(const char *p, UTC u); +extern void time_print_epoch(const char *p, EPOCH e); +/* ntp.c */ +/* dcf77.c */ +extern uint64_t dcf77_last_second; +extern void exti15_10_isr(void); +extern void dcf77_dispatch(void); +extern void dcf77_init(void); +/* util.c */ +extern int check_parity(uint8_t *d, unsigned s, unsigned e, uint8_t p); +extern unsigned bcd(uint8_t *d, unsigned s, unsigned e); +extern unsigned le_bcd(uint8_t *d, unsigned s, unsigned e); +/* stats.c */ +extern void stats(void); +extern void stats_stamp(UTC m, uint64_t abs); diff --git a/app/steth.c b/app/steth.c index 2aa847f..ba3aa72 100644 --- a/app/steth.c +++ b/app/steth.c @@ -172,16 +172,21 @@ steth_nis (void) void eth_isr (void) { + if (eth_irq_ack_pending (ETH_DMASR_NIS)) + steth_nis(); } void steth_isr (void) { +#if 0 // printf ("eth\r\n"); if (eth_irq_ack_pending (ETH_DMASR_NIS)) steth_nis(); +#endif + } @@ -321,7 +326,7 @@ steth_init (void) running++; - printf ("Running\n"); + printf ("Running\r\n"); } diff --git a/app/time_fn.c b/app/time_fn.c index 5636ef1..1067dd9 100644 --- a/app/time_fn.c +++ b/app/time_fn.c @@ -210,16 +210,16 @@ EPOCH time_utc_to_epoch (UTC u) } -void time_print_utc (UTC u) +void time_print_utc (const char *p, UTC u) { const char *dname[] = {"Sun", "Mon", "Tue", "Wed", "Thr", "Fri", "Sat", "Sun"}; const char *mname[] = {"", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; - printf ("%s %04d-%s-%02d %02d:%02d:%02d.%09d\r\n", dname[u.wday], u.year, mname[u.month], u.mday, u.hour, u.minute, u.second, u.nanosecond); + printf ("%s%s %04d-%s-%02d %02d:%02d:%02d.%09d\r\n", p ? p : "", dname[u.wday], u.year, mname[u.month], u.mday, u.hour, u.minute, u.second, u.nanosecond); } -void time_print_epoch (EPOCH e) +void time_print_epoch (const char *p, EPOCH e) { UTC u = time_epoch_to_utc (e); - time_print_utc (u); + time_print_utc (p, u); } diff --git a/app/time_fn.h b/app/time_fn.h index 7cf75d3..a1a4602 100644 --- a/app/time_fn.h +++ b/app/time_fn.h @@ -12,8 +12,8 @@ typedef struct { } UTC; typedef struct { - uint64_t s; - uint64_t ns; + int64_t s; + int64_t ns; } EPOCH; -- cgit v1.2.3