From 6d3a824e1cdae6e28146b7de380724b49488f3c2 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 25 Feb 2021 19:12:38 +0000 Subject: tim --- app/Makefile | 9 +- app/dcf77.c | 8 +- app/gps.c | 368 +++++++++++++++++++++++++++++++++++++++++++++---------- app/lwip_glue.c | 8 +- app/main.c | 92 ++++---------- app/max7219.c | 111 +++++++++++++++-- app/msf.c | 6 +- app/pll.c | 8 +- app/project.h | 28 +++-- app/prototypes.h | 26 +++- app/report.c | 2 +- app/ticker.c | 5 +- app/time_fn.c | 125 ++++++++++++++++++- app/time_fn.h | 8 ++ app/ubx.h | 15 +++ 15 files changed, 638 insertions(+), 181 deletions(-) diff --git a/app/Makefile b/app/Makefile index d4c56c5..f38aea4 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 dcf77.c util.c stats.c gps.c hexdump.c bits.c max7219.c report.c sysclk.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 gps.c hexdump.c bits.c max7219.c report.c sysclk.c cdcacm.c usb.c HSRCS= events.h gps.h project.h ring.h steth.h time_fn.h ubx.h @@ -71,11 +71,16 @@ include ../Makefile.include CFLAGS+=-Wno-redundant-decls -Wno-unused-parameter CPPFLAGS += -I../libopencm3-local -I${LWIP_PATH}/${LWIP}/src/include -Ilwip -I${LWIP_PATH}/${LWIP}/src/include/ipv4 -I${LWIP_LOCAL}/port/stm32f4x7 -I. + +LDLIBS+= -lm + fish: ${OBJS} echo ${OBJS} -HOST=clock-lnx +#HOST=clock-lnx #HOST=10.32.91.140 +HOST=tick +HOST=10.32.96.46 reset: diff --git a/app/dcf77.c b/app/dcf77.c index fc2dcda..124eea5 100644 --- a/app/dcf77.c +++ b/app/dcf77.c @@ -124,7 +124,7 @@ void dcf77_dispatch (void) { static uint32_t last_0, last_1, last_s; static int second, bit, had_m; - uint32_t pulse_w, offset; + uint32_t pulse_w,offset ; static uint64_t abs; int is_s = 0; @@ -147,7 +147,7 @@ void dcf77_dispatch (void) if (v) { pulse_w = now - last_0; - pulse_w /= (HZ / 1000); + pulse_w /= (HW_CLOCK_HZ / 1000); last_1 = now; @@ -165,7 +165,7 @@ void dcf77_dispatch (void) } else { pulse_w = now - last_1; - pulse_w /= (HZ / 1000); + pulse_w /= (HW_CLOCK_HZ / 1000); if (pulse_w > 150) bit = 1; @@ -182,7 +182,7 @@ void dcf77_dispatch (void) } offset = now - last_s; - offset /= (HZ / 1000); + offset /= (HW_CLOCK_HZ / 1000); if (is_s) { abs = abs_extend (now); diff --git a/app/gps.c b/app/gps.c index c3ac2d1..101413f 100644 --- a/app/gps.c +++ b/app/gps.c @@ -14,6 +14,7 @@ static EPOCH next_sec; static int ubx_ack = 0; +static int ubx_nack = 0; static int ubx_ack_xfer = 0; static int current_ref_hz = 1; @@ -32,6 +33,9 @@ static Event_ring gps_ring; static char gps_info[60]; +static int ubx_cfg_tmode (uint32_t time_mode, int32_t x, int32_t y, int32_t z, + uint32_t var, uint32_t min_dur, uint32_t max_var); + void exti9_5_isr (void) { uint32_t now = HW_CLOCK_REG; @@ -98,12 +102,44 @@ static int ubx_recv_almanac (uint8_t *ptr, unsigned len) return 0; } +double gps_lat, gps_lon; + +static int +ubx_recv_nav_posllh (uint8_t *ptr, unsigned len) +{ + uint32_t d; + int32_t ilat, ilon, i; + + if ((!ptr) || (len != 28)) + return -1; + + ptr += ubx_get_u32 (ptr, &d); //TOW + ptr += ubx_get_i32 (ptr, &ilon); + ptr += ubx_get_i32 (ptr, &ilat); + ptr += ubx_get_i32 (ptr, &i); //geoid height + ptr += ubx_get_i32 (ptr, &i); //msl height + ptr += ubx_get_u32 (ptr, &d); //hacc + ptr += ubx_get_u32 (ptr, &d); //vacc + + + gps_lat = 1.e-7 * (double) ilat; + gps_lon = 1.e-7 * (double) ilon; + + + printf ("POS: %.4f %.4f\r\n", gps_lat, gps_lon); + + return 0; +} + + static int ubx_recv_nav_status (uint8_t *ptr, unsigned len) { uint8_t gps_fix, flags, fix_stat, flags2; uint32_t d; + unsigned kick_off_survey_mode=300; + if ((!ptr) || (len != 16)) return -1; @@ -138,7 +174,8 @@ ubx_recv_nav_status (uint8_t *ptr, unsigned len) case 5: fix = 'T'; - gps_locked = 0; + gps_locked = 1; + kick_off_survey_mode=0; break; default: @@ -169,7 +206,7 @@ ubx_recv_nav_status (uint8_t *ptr, unsigned len) } - // printf ("fix: %c%c\r\n",fix,fix2); + // printf ("fix: %c%c happy %d Fix %02x flags %02x fix_stat %02x flags2 %02x \r\n",fix,fix2,gps_happy, gps_fix, flags,fix_stat,flags2); if ((gps_locked) && (gps_happy < 10000)) @@ -177,6 +214,16 @@ ubx_recv_nav_status (uint8_t *ptr, unsigned len) else gps_happy = 0; + + if (kick_off_survey_mode>0) { + kick_off_survey_mode--; + + if (!kick_off_survey_mode) { + printf("GPS no time fix - kicking off survey mode\n"); + ubx_cfg_tmode (1, 0, 0, 0, 0, 3600, 3600); // 1 hour and 6cm + } + } + return 0; } @@ -207,20 +254,24 @@ ubx_recv_clock_stats (uint8_t *ptr, unsigned len) } +int gps_utc_diff; +int gps_wday; + static int ubx_recv_utc (uint8_t *ptr, unsigned len) { int32_t nano; uint32_t acc; + uint32_t tow; + int tod, utc_tod; uint16_t year; uint8_t hour, min, sec, day, month, valid; - uint32_t d; // char buf[40]; if ((!ptr) || (len != 20)) return -1; - ptr += ubx_get_u32 (ptr, &d); //TOW + ptr += ubx_get_u32 (ptr, &tow); //TOW ptr += ubx_get_u32 (ptr, &acc); //bias ptr += ubx_get_i32 (ptr, &nano); ptr += ubx_get_u16 (ptr, &year); @@ -270,8 +321,11 @@ ubx_recv_utc (uint8_t *ptr, unsigned len) u.second = sec; u.nanosecond = 0; + + gps_time = time_utc_to_epoch (u); + next_sec = gps_time; now = HW_CLOCK_REG; @@ -281,8 +335,22 @@ ubx_recv_utc (uint8_t *ptr, unsigned len) pll_set_offset (gps_time, abs); - } + } else + printf ("!GPS %s\r\n", gps_info); + +#define SECONDS_IN_DAY (24*60*60) + + utc_tod = (((hour * 60) + min) * 60) + sec; + tow /= 1000; + tod = tow % SECONDS_IN_DAY; + gps_wday = tow / SECONDS_IN_DAY; + utc_tod += 2 * SECONDS_IN_DAY; + utc_tod -= tod; + + while (utc_tod >= (SECONDS_IN_DAY / 2)) utc_tod -= SECONDS_IN_DAY; + + gps_utc_diff = utc_tod; #if 0 sprintf (buf, "%+6dE-12 %02d%02d%02d", (int) freq, @@ -298,12 +366,13 @@ ubx_recv_utc (uint8_t *ptr, unsigned len) static int ubx_recv_nav_sbas (uint8_t *ptr, unsigned len) { + uint32_t d4; uint8_t prn, mode, service; int8_t sys; uint8_t n; - ptr += 4; + ptr += ubx_get_u32 (ptr, &d4); ptr += ubx_get_u8 (ptr, &prn); ptr += ubx_get_u8 (ptr, &mode); ptr += ubx_get_i8 (ptr, &sys); @@ -312,35 +381,78 @@ static int ubx_recv_nav_sbas (uint8_t *ptr, unsigned len) ptr += ubx_get_u8 (ptr, &n); ptr += 3; - printf ("GPS SBAS PRN:%d M:%d S:%d SVC:%02x\r\n", prn, mode, sys, service); +// printf ("GPS SBAS PRN:%d M:%d S:%d SVC:%02x SVS:", prn, mode, sys, service); while (n--) { ptr += ubx_get_u8 (ptr, &prn); ptr += 11; - printf ("GPS SBAS SV:%d\r\n", prn); + printf (" %d", prn); } + printf ("\r\n"); return 0; } -static int ubx_recv_nav_sat (uint8_t *ptr, unsigned len) +static int ubx_recv_nav_svinfo (uint8_t *ptr, unsigned len) { - uint8_t gnssid, prn, cno, ver; - uint8_t n; + uint32_t d4; + uint16_t d2; + uint8_t ch, quality, cno, svid; + uint8_t n, flags, cflags; + const char *st; - ptr += 4; + return 0; - ptr += ubx_get_u8 (ptr, &ver); + ptr += ubx_get_u32 (ptr, &d4); ptr += ubx_get_u8 (ptr, &n); - ptr += 2; + ptr += ubx_get_u8 (ptr, &flags); + ptr += ubx_get_u16 (ptr, &d2); while (n--) { - ptr += ubx_get_u8 (ptr, &gnssid); - ptr += ubx_get_u8 (ptr, &prn); + ptr += ubx_get_u8 (ptr, &ch); + ptr += ubx_get_u8 (ptr, &svid); + ptr += ubx_get_u8 (ptr, &cflags); + ptr += ubx_get_u8 (ptr, &quality); ptr += ubx_get_u8 (ptr, &cno); - ptr += 9; + ptr += 7; + + switch (quality) { + case 0: + st = "idle"; + break; + + case 1: + st = "search"; + break; - printf ("GPS GNSS:%2d PRN:%3d CNO:%3d\r\n", gnssid, prn, cno); + case 2: + st = "acq"; + break; + + case 3: + st = "inop"; + break; + + case 4: + st = "lock"; + break; + + case 5: + case 6: + case 7: + st = "good"; + break; + + default: + st = "?"; + } + + printf ("GPS SVID:%3d C/N:%3d %c%c%c %s\r\n", + svid, cno, + (cflags & 0x01) ? 'U' : '-', + (cflags & 0x02) ? 'D' : '-', + (cflags & 0x04) ? 'E' : '-', + st); } @@ -355,16 +467,41 @@ static int ubx_recv_rinex (uint8_t *payload, unsigned len) return 0; } +static int ubx_recv_tim_svin (uint8_t *ptr, unsigned len) +{ + uint8_t valid, active; + uint32_t dur, obs, var; + int32_t x, y, z; + + ptr += ubx_get_u32 (ptr, &dur); + ptr += ubx_get_i32 (ptr, &x); + ptr += ubx_get_i32 (ptr, &y); + ptr += ubx_get_i32 (ptr, &z); + ptr += ubx_get_u32 (ptr, &var); + ptr += ubx_get_u32 (ptr, &obs); + ptr += ubx_get_u8 (ptr, &valid); + ptr += ubx_get_u8 (ptr, &active); + + printf ("TIM-SVIN dur %u var %u obs %u valid %02x active %02x\r\n", + (unsigned) dur, (unsigned) var, (unsigned) obs, valid, active); + + return 0; +} + static void ubx_recv (uint8_t class, uint8_t id, uint8_t *payload, unsigned len) { - // printf ("RX> %02x.%02x (%d bytes)\r\n", class, id, len); + //printf ("RX> %02x.%02x (%d bytes)\r\n", class, id, len); switch (class) { case 1: switch (id) { + case 0x2: + ubx_recv_nav_posllh (payload, len); + break; + case 0x3: ubx_recv_nav_status (payload, len); break; @@ -377,13 +514,14 @@ ubx_recv (uint8_t class, uint8_t id, uint8_t *payload, unsigned len) ubx_recv_clock_stats (payload, len); break; + case 0x30: + ubx_recv_nav_svinfo (payload, len); + break; + case 0x32: ubx_recv_nav_sbas (payload, len); break; - case 0x35: - ubx_recv_nav_sat (payload, len); - break; default: printf ("RX> %02x.%02x (%d bytes)\r\n", class, id, len); @@ -414,10 +552,29 @@ ubx_recv (uint8_t class, uint8_t id, uint8_t *payload, unsigned len) break; + case 0xd: + switch (id) { + case 0x4: + ubx_recv_tim_svin (payload, len); + + break; + + default: + printf ("RX> %02x.%02x (%d bytes)\r\n", class, id, len); + hexdump (payload, len); + } + + break; + + + case 5: ubx_ack++; + + if (!id) ubx_nack++; + printf (" %s for %02x.%02x\r\n", id ? "ACK" : "NAK", payload[0], payload[1]); @@ -651,38 +808,35 @@ ubx_send (uint8_t class, uint8_t id, const void *_payload, unsigned len) ubx_send_byte (ck_a); ubx_send_byte (ck_b); - // printf ("TX> %02x.%02x\r\n", class, id); + printf ("TX> %02x.%02x\r\n", class, id); } static int ubx_handshake (uint8_t class, uint8_t id, const void *payload, unsigned len) { - uint32_t timeout; + uint32_t timeout=4000; ubx_ack = 0; + ubx_nack = 0; ubx_send (class, id, payload, len); - - - timeout = ticks + TIMEOUT; - while (!ubx_ack) { - if (ticks > timeout) { + if (!timeout) { printf ("GPS timeout resending packet\r\n"); usart1_drain(); ubx_send (class, id, payload, len); - timeout = ticks + TIMEOUT; + timeout = 40000; } - - + timeout--; gps_dispatch(); + delay_ms(1); } - return 0; + return !!ubx_nack; } static int @@ -754,6 +908,7 @@ static int ubx_set_message_rate_port1 (uint8_t class, uint8_t id, uint8_t rate) { uint8_t buf[8], *ptr; + int ret; ptr = buf; @@ -766,7 +921,10 @@ ubx_set_message_rate_port1 (uint8_t class, uint8_t id, uint8_t rate) ptr += ubx_put_u8 (ptr, 0); //nothing on spi ptr += ubx_put_u8 (ptr, 0); //nothing on port 5 - return ubx_handshake (0x06, 0x01, buf, (unsigned) (ptr - buf)); + ret = ubx_handshake (0x06, 0x01, buf, (unsigned) (ptr - buf)); + + printf ("GPS set message rate for %02x.%02x %s\r\n", class, id, ret ? "Failed" : "Succeeded"); + return ret; } @@ -785,6 +943,70 @@ ubx_cfg_rst (uint16_t flags) return 0; } +static int +ubx_cfg_poll (uint8_t class, uint8_t id) +{ + return ubx_handshake (class, id, NULL, 0); +} + +static int ubx_cfg_sbas (uint8_t mode, uint8_t usage, uint8_t channels) +{ + uint8_t buf[8], *ptr; + + ptr = buf; + + ptr += ubx_put_u8 (ptr, mode); + ptr += ubx_put_u8 (ptr, usage); + ptr += ubx_put_u8 (ptr, channels); + ptr += ubx_put_u8 (ptr, 0x0); + ptr += ubx_put_u32 (ptr, /* 0x1 PRN 120 | */ 0x8 /*PRN 123*/ | /* 0x40 PRN 126 | */ 0x10000 /*PRN136*/); + + return ubx_handshake (0x06, 0x16, buf, (unsigned) (ptr - buf)); +} + + +static int ubx_cfg_tmode (uint32_t time_mode, int32_t x, int32_t y, int32_t z, + uint32_t var, uint32_t min_dur, uint32_t max_var) +{ + uint8_t buf[28], *ptr; + + ptr = buf; + + ptr += ubx_put_u32 (ptr, time_mode); + ptr += ubx_put_i32 (ptr, x); + ptr += ubx_put_i32 (ptr, y); + ptr += ubx_put_i32 (ptr, z); + ptr += ubx_put_u32 (ptr, var); + ptr += ubx_put_u32 (ptr, min_dur); + ptr += ubx_put_u32 (ptr, max_var); + + return ubx_handshake (0x06, 0x1d, buf, (unsigned) (ptr - buf)); +} + +static int ubx_aid_ini (int32_t lat, int32_t lon, int32_t alt, uint32_t acc) +{ + uint8_t buf[48], *ptr; + + ptr = buf; + + ptr += ubx_put_i32 (ptr, lat); + ptr += ubx_put_i32 (ptr, lon); + ptr += ubx_put_i32 (ptr, alt); + ptr += ubx_put_u32 (ptr, acc); + ptr += ubx_put_u16 (ptr, 0); //time mark flags + ptr += ubx_put_u16 (ptr, 0); // week number + ptr += ubx_put_u32 (ptr, 0); // tow s + ptr += ubx_put_i32 (ptr, 0); // tow ns + ptr += ubx_put_u32 (ptr, 0); // tow accuracy ms + ptr += ubx_put_u32 (ptr, 0); // tow accuracy ns + ptr += ubx_put_i32 (ptr, 0); // clock drift or freq + ptr += ubx_put_u32 (ptr, 0); // clock drift or freq accuracy + ptr += ubx_put_u32 (ptr, 0x21); //flags LLA no time + + return ubx_handshake (0x0b, 0x01, buf, (unsigned) (ptr - buf)); + //return ubx_send (0x0b, 0x01, NULL, 0); + +} static int gps_set_ref (int ref_hz) @@ -794,34 +1016,48 @@ gps_set_ref (int ref_hz) printf ("setting gps ref to %d hz\r\n", ref_hz); + /*Try ublox 5 version first */ + current_ref_hz = ref_hz; ptr = buf; + ptr += ubx_put_u32 (ptr, 1000000 / ref_hz); //period /us + ptr += ubx_put_u32 (ptr, 1000); //duration /us + ptr += ubx_put_i8 (ptr, 1); //+ve sense + ptr += ubx_put_u8 (ptr, 1); //lock to utc + ptr += ubx_put_u8 (ptr, 0); //pulse only when locked + ptr += ubx_put_u8 (ptr, 0); //res + + /* 50.52 ns from 10m of RG58 */ + /* 15.15 ns from 3m of RG174 */ + /* total 66ns*/ + + ptr += ubx_put_i16 (ptr, 66); //antenna cable delay /ns + ptr += ubx_put_i16 (ptr, 0); //rf group delay /ns + ptr += ubx_put_i32 (ptr, 0); //user delay /ns + + ret = ubx_handshake (0x06, 0x07, buf, (unsigned) (ptr - buf)); + + if (!ret) return ret; + + ptr = buf; + ptr += ubx_put_u8 (ptr, 0); //timepluse 1 ptr += ubx_put_u8 (ptr, 0); //version 0 ptr += ubx_put_u16 (ptr, 0); //reserved - // ptr += ubx_put_u16 (ptr, 32); //ant cable delay ns ptr += ubx_put_u16 (ptr, 0); //ant cable delay ns ptr += ubx_put_u16 (ptr, 0); //rf group delay ns - ptr += ubx_put_u32 (ptr, 1000000 / ref_hz); //period unlocked/us + ptr += ubx_put_u32 (ptr, 0); //period unlocked/us ptr += ubx_put_u32 (ptr, 1000000 / ref_hz); //period locked/us // ptr += ubx_put_u32 (ptr, 0); //pulse width unlocked/us - ptr += ubx_put_u32 (ptr, 100000 / ref_hz); //pulse width unlocked/us - ptr += ubx_put_u32 (ptr, 100000 / ref_hz); //pulse width locked/us + ptr += ubx_put_u32 (ptr, 0); //pulse width unlocked/us + ptr += ubx_put_u32 (ptr, 1000 / ref_hz); //pulse width locked/us ptr += ubx_put_i32 (ptr, 0); // ? delay - -#if 0 - /*Separate numbers for locked/unlocked*/ ptr += ubx_put_u32 (ptr, 0xf7); -#else - /*Same numbers for locked/unlocked*/ - ptr += ubx_put_u32 (ptr, 0xf7); -#endif - ret = ubx_handshake (0x06, 0x31, buf, (unsigned) (ptr - buf)); @@ -833,7 +1069,7 @@ int gps_init (void) { uint8_t buf[80], *ptr; - unsigned len; + //unsigned len; // uint16_t u2; usart1_drain(); @@ -911,27 +1147,36 @@ gps_init (void) gps_set_ref (1); +#if 0 ubx_fetch (0x06, 0x31, NULL, 0, &len); - printf ("configured GNSS 6.31\r\n"); +#endif ubx_set_nav_rate (1000); #if 1 + ubx_set_message_rate_port1 (0x01, 0x02, 10); ubx_set_message_rate_port1 (0x01, 0x03, 1); ubx_set_message_rate_port1 (0x01, 0x06, 0); ubx_set_message_rate_port1 (0x01, 0x21, 1); ubx_set_message_rate_port1 (0x01, 0x22, 1); - ubx_set_message_rate_port1 (0x01, 0x32, 0); - ubx_set_message_rate_port1 (0x01, 0x32, 0); /*SBAS*/ - ubx_set_message_rate_port1 (0x01, 0x35, 0); /*SV in view*/ + ubx_set_message_rate_port1 (0x01, 0x30, 10); /*SV in view*/ + ubx_set_message_rate_port1 (0x01, 0x32, 10); /*SBAS*/ - ubx_set_message_rate_port1 (0x03, 0x0a, 0); - ubx_set_message_rate_port1 (0x03, 0x10, 0); - ubx_set_message_rate_port1 (0x03, 0x21, 0); - ubx_set_message_rate_port1 (0x04, 0x04, 0); + // ubx_set_message_rate_port1 (0x03, 0x0a, 0); + // ubx_set_message_rate_port1 (0x03, 0x10, 0); + // ubx_set_message_rate_port1 (0x03, 0x21, 0); //? + // ubx_set_message_rate_port1 (0x04, 0x04, 0); + + ubx_set_message_rate_port1 (0x0D, 0x04, 10); + + ubx_cfg_sbas (1, 0x7, 2); + + ubx_cfg_poll (0x6, 0x16); + +// ubx_aid_ini (522202400, 1279080, 2900, 20000); printf ("GNSS ready\r\n"); #else @@ -944,19 +1189,6 @@ gps_init (void) printf ("GNSS ready\r\n"); #endif -#if 0 - ptr = buf; - ptr += ubx_put_u8 (ptr, 0x1); - ptr += ubx_put_u8 (ptr, 0x7); - ptr += ubx_put_u8 (ptr, 0x1); - ptr += ubx_put_u8 (ptr, 0xf); - ptr += ubx_put_u32 (ptr, 0xffffffff); - ubx_handshake (0x06, 0x16, buf, (unsigned) (ptr - buf)); - - printf ("configured SBAS\r\n"); - - ubx_handshake (0x06, 0x16, buf, 0); -#endif // printf ("GPS ready\r\n"); diff --git a/app/lwip_glue.c b/app/lwip_glue.c index 03380a4..1e69fc0 100644 --- a/app/lwip_glue.c +++ b/app/lwip_glue.c @@ -59,17 +59,17 @@ void start_lwip (void) lwip_init(); -#if 1 +#if 0 IP4_ADDR (&ipaddr, 10, 32, 99, 73); IP4_ADDR (&netmask, 255, 255, 255, 0); IP4_ADDR (&gw, 10, 32, 99, 1); #else - IP4_ADDR (&ipaddr, 192, 168, 1, 1); + IP4_ADDR (&ipaddr, 10, 32, 96, 47); IP4_ADDR (&netmask, 255, 255, 255, 0); - IP4_ADDR (&gw, 192, 168, 1, 254); + IP4_ADDR (&gw, 10, 32, 96, 1); #endif - netif_add (&if0, &ipaddr, &netmask, &gw, NULL, steth_lwip_init , ethernet_input); + netif_add (&if0, &ipaddr, &netmask, &gw, NULL, steth_lwip_init, ethernet_input); /* Registers the default network interface.*/ netif_set_default (&if0); diff --git a/app/main.c b/app/main.c index e3e3f63..22ee23e 100644 --- a/app/main.c +++ b/app/main.c @@ -138,6 +138,7 @@ static const clock_scale_t hse_10mhz_3v3_168 = { .apb2_frequency = 84000000, }; + #if 0 static const clock_scale_t hse_10mhz_3v3_120 = { /* 120 */ @@ -202,69 +203,6 @@ static const clock_scale_t hse_10mhz_3v3_10 = { #endif -/* - * Erugh the STM32F4's PLL is shite, we need - * to drive the entire clock tree from the 10MHz - * input, we use the PLL only to drive the 48MHz - * clock tree. - * - * So PTP, AHB, APB1, APB2 all are directly from - * the HSE input - */ - - -void rcc_clock_setup_hse_3v3_no_pll (const clock_scale_t *clock) -{ - /* Enable internal high-speed oscillator. */ - rcc_osc_on (HSI); - rcc_wait_for_osc_ready (HSI); - - /* Select HSI as SYSCLK source. */ - rcc_set_sysclk_source (RCC_CFGR_SW_HSI); - - /* receive the 10MHz external oscillator */ - rcc_osc_bypass_enable (HSE); - rcc_osc_on (HSE); - rcc_wait_for_osc_ready (HSE); - - /* Enable/disable high performance mode */ - if (!clock->power_save) - pwr_set_vos_scale (SCALE1); - else - pwr_set_vos_scale (SCALE2); - - /* - * Set prescalers for AHB, ADC, ABP1, ABP2. - * Do this before touching the PLL (TODO: why?). - */ - rcc_set_hpre (clock->hpre); - rcc_set_ppre1 (clock->ppre1); - rcc_set_ppre2 (clock->ppre2); - - rcc_set_main_pll_hse (clock->pllm, clock->plln, - clock->pllp, clock->pllq); - - /* Enable PLL oscillator and wait for it to stabilize. */ - rcc_osc_on (PLL); - rcc_wait_for_osc_ready (PLL); - - /* Configure flash settings. */ - flash_set_ws (clock->flash_config); - - /* Select HSE as SYSCLK source. */ - rcc_set_sysclk_source (RCC_CFGR_SW_HSE); - - /* Wait for HSE clock to be selected. */ - rcc_wait_for_sysclk_status (HSE); - - /* Set the peripheral clock frequencies used. */ - rcc_apb1_frequency = clock->apb1_frequency; - rcc_apb2_frequency = clock->apb2_frequency; - - /* Disable internal high-speed oscillator. */ - rcc_osc_off (HSI); -} - static void ptp_clock_start (void) { /* Get the PTP clock running early */ @@ -283,6 +221,7 @@ static void ptp_clock_start (void) static void clock_setup (void) { +static uint32_t fail; /* * Caution, The PLL is somewhat rubbish, and causes all sorts of misery * so sysclk isn't really a reference, if we use it, however not using it @@ -292,8 +231,26 @@ static void clock_setup (void) * */ + /*Get us up and running on the 16MHz RC clock */ + rcc_osc_on (HSI); + rcc_wait_for_osc_ready (HSI); + + /* Select HSI as SYSCLK source. */ + rcc_set_sysclk_source (RCC_CFGR_SW_HSI); + + /* confiure HSE as input not oscillator */ - rcc_osc_bypass_enable (HSE); + rcc_osc_bypass_enable (HSE); + rcc_osc_on (HSE); + + while ((RCC_CR & RCC_CR_HSERDY) == 0) { + if (fail++ == 4000000) { + /*No external clock, try seeing if we have a crystal */ + rcc_osc_off (HSE); + rcc_osc_bypass_disable (HSE); + rcc_osc_on (HSE); + } + } /* turn off SSC */ RCC_SSCGR = 0; @@ -406,6 +363,7 @@ board_setup (void) rcc_periph_clock_enable (RCC_ETHMACPTP); rcc_periph_clock_enable (RCC_TIM1); rcc_periph_clock_enable (RCC_TIM2); + rcc_periph_clock_enable (RCC_OTGFS); nvic_set_priority (NVIC_EXTI9_5_IRQ, 0x00); nvic_set_priority (NVIC_EXTI3_IRQ, 0x10); @@ -420,6 +378,7 @@ board_setup (void) } + static void system_init (void) { @@ -443,11 +402,13 @@ system_init (void) ptp_clock_start(); - max7219_init (1); + max7219_init (1, 8); gps_init(); ntp_init(); + usb_init(); + } int @@ -495,6 +456,7 @@ main (void) dispatch_lwip(); max7219_dispatch(); + cdcacm_dispatch(); } diff --git a/app/max7219.c b/app/max7219.c index bebfa50..8c1c859 100644 --- a/app/max7219.c +++ b/app/max7219.c @@ -30,6 +30,7 @@ set (int sck, int ncs, int mosi) else CLEAR (MOSI); + // delay_us(1); //delay_us(10); } @@ -80,40 +81,124 @@ write_reg (uint8_t reg, uint8_t data) spip_send_8 (reg); spip_send_8 (data); + spip_send_8 (reg); + spip_send_8 (data); + + spip_send_8 (reg); + spip_send_8 (data); + set (0, 0, 0); set (0, 1, 0); unlock(); } -static void write_pair (uint8_t reg, int d) + +static void +write_regs (uint8_t reg, uint8_t data1, uint8_t data2, uint8_t data3) { - write_reg (reg, d / 10); - write_reg (reg - 1, (d % 10) | 0x80); + while (lock()); + + set (0, 1, 0); + set (0, 0, 0); + + spip_send_8 (reg); + spip_send_8 (data3); + + spip_send_8 (reg); + spip_send_8 (data2); + + spip_send_8 (reg); + spip_send_8 (data1); + + set (0, 0, 0); + set (0, 1, 0); + unlock(); } -void max7219_write (int d, int h, int m, int s) +static void write_pair (uint8_t reg, int d1, int d2, int d3) +{ + write_regs (reg, d1 / 10, d2 / 10, d3 / 10); + write_regs (reg - 1, (d1 % 10) | 0x80, (d2 % 10) | 0x80, (d3 % 10) | 0x80); +} + + +#if 0 +static void st_test (void) { - write_pair (8, d); - write_pair (6, h); - write_pair (4, m); - write_pair (2, s); + UTC u = { 0 }; + double local_lon = 0.0; + ST st; + double ra; + + // LEDS: 12.13.28.00 01.01.29.05 13.27.42.05 + + u.year = 2021; + u.month = 1; + u.mday = 12; + u.hour = 13; + u.minute = 28; + + ra = time_utc_to_ra (u); + st = time_ra_to_st (ra + local_lon); + + printf ("%d:%02d:%02d\n", st.hour, st.minute, st.second); + + st = time_utc_to_lst (u, local_lon); + printf ("%d:%02d:%02d\n", st.hour, st.minute, st.second); + + for (;;); } +#endif + void max7219_dispatch (void) { uint32_t now = HW_CLOCK_REG; uint64_t abs = abs_extend (now); - EPOCH e = pll_decompose (abs); - UTC u = time_epoch_to_utc (e); + static unsigned m; + EPOCH e; + UTC u; + UTC gu; + ST l; + + + e = pll_decompose (abs); + u = time_epoch_to_utc (e); + l = time_utc_to_lst (u, gps_lon); + + e.s += gps_utc_diff; + gu = time_epoch_to_utc (e); + + write_pair (8, u.hour, l.hour, gps_wday); + write_pair (6, u.minute, l.minute, gu.hour); + write_pair (4, u.second, l.second, gu.minute); + write_pair (2, u.nanosecond / 10000000, l.nanosecond / 10000000, gu.second); + + if (u.minute == m) return; + + m = u.minute; + + printf ("LEDS: %02d.%02d.%02d.%02d %02d.%02d.%02d.%02d %02d.%02d.%02d.%02d lon %.6f\r\n", + u.hour, u.minute, u.second, + u.nanosecond / 10000000, + l.hour, + l.minute, + l.second, + l.nanosecond / 10000000, + gps_wday, + gu.hour, + gu.minute, + gu.second, + gps_lon); + - max7219_write (u.mday, u.hour, u.minute, u.second); } void -max7219_init (int on) +max7219_init (int on, int brightness) { MAP_OUTPUT_PP (SCK); MAP_OUTPUT_PP (NCS); @@ -129,7 +214,7 @@ max7219_init (int on) write_reg (0x9, 0xff); //BCD decode write_reg (0xb, 0x7); //8 digits - write_reg (0xa, 0x8); //intensity + write_regs (0xa, brightness, brightness, brightness); } else { write_reg (0xc, 0x0); //Power up } diff --git a/app/msf.c b/app/msf.c index 9d8db3f..ab85cfe 100644 --- a/app/msf.c +++ b/app/msf.c @@ -171,7 +171,7 @@ void msf_dispatch (void) if (v) { pulse_w = now - last_0; - pulse_w /= (HZ / 1000); + pulse_w /= (HW_CLOCK_HZ / 1000); if (pulse_w > 300) { last_s = now; @@ -183,7 +183,7 @@ void msf_dispatch (void) } else { pulse_w = now - last_1; - pulse_w /= (HZ / 1000); + pulse_w /= (HW_CLOCK_HZ / 1000); if (pulse_w > 400) { had_m = 1; @@ -194,7 +194,7 @@ void msf_dispatch (void) } offset = now - last_s; - offset /= (HZ / 1000); + offset /= (HW_CLOCK_HZ / 1000); if (is_s) { diff --git a/app/pll.c b/app/pll.c index 986034c..19681d8 100644 --- a/app/pll.c +++ b/app/pll.c @@ -8,7 +8,7 @@ static int64_t offset; static int64_t phase; -int64_t pll_freq = HZ; +int64_t pll_freq = HW_CLOCK_HZ; static int out_of_lock = JUMP_TICKS + 1; @@ -102,7 +102,7 @@ static void modify_pll_freq (uint64_t now, int d) uint64_t make_happy (uint64_t abs, int64_t shift) { - shift *= HZ; + shift *= HW_CLOCK_HZ; if (shift < 0) { shift = -shift; @@ -170,7 +170,7 @@ void pll_dispatch (uint64_t happy, uint64_t edge, const char *src) if (happy < msf_last_happy) return; - if (!pll_ready && (edge < ((uint64_t) WARM_UP * (uint64_t) HZ))) + if (!pll_ready && (edge < ((uint64_t) WARM_UP * (uint64_t) HW_CLOCK_HZ))) return; led_blink (100); @@ -211,7 +211,7 @@ void pll_dispatch (uint64_t happy, uint64_t edge, const char *src) phase += pd; out_of_lock = 0; printf ("PLL - jumping\r\n"); - pll_freq = HZ; + pll_freq = HW_CLOCK_HZ; pll_ready = 1; } else { diff --git a/app/project.h b/app/project.h index d060a81..5785628 100644 --- a/app/project.h +++ b/app/project.h @@ -5,6 +5,14 @@ #include #include #include + +/* Core */ +#include +#include +#include +#include +#include +/* SoC */ #include #include #include @@ -16,14 +24,18 @@ #include #include #include +#include +#include +#include +/* Drivers */ #include #include -#include -#include -#include -#include -#include -#include +#include +#include +#ifdef INCLUDE_DFU_INTERFACE +#include +#endif + #include @@ -47,7 +59,7 @@ #include "prototypes.h" //#define HZ 10000000 -#define HZ 10000000 +#define HW_CLOCK_HZ 10000000 //#define HZ 167999973 //#define HZ 168000000 @@ -72,3 +84,5 @@ extern const unsigned char almanac_alp[]; extern unsigned int almanac_alp_len; +#define ID_VENDOR 0x0483 +#define ID_PRODUCT 0x5740 diff --git a/app/prototypes.h b/app/prototypes.h index 8779f8d..f409da8 100644 --- a/app/prototypes.h +++ b/app/prototypes.h @@ -78,7 +78,6 @@ extern EPOCH pll_decompose_diff(int64_t diff); extern EPOCH pll_decompose(uint64_t abs); /* main.c */ extern int time_known; -extern void rcc_clock_setup_hse_3v3_no_pll(const clock_scale_t *clock); extern int main(void); /* time_fn.c */ extern UTC time_epoch_to_utc(EPOCH epoch); @@ -86,6 +85,10 @@ extern EPOCH time_utc_to_epoch(UTC u); extern void utc_to_str(char *dst, UTC u); extern void time_print_utc(const char *p, UTC u, const char *t); extern void time_print_epoch(const char *p, EPOCH e, const char *t); +extern double time_utc_to_tjd(UTC u); +extern double time_utc_to_ra(UTC u); +extern ST time_ra_to_st(double ra); +extern ST time_utc_to_lst(UTC u, double lon); /* ntp.c */ extern void ntp_init(void); /* dcf77.c */ @@ -101,6 +104,10 @@ extern unsigned le_bcd(uint8_t *d, unsigned s, unsigned e); /* gps.c */ extern uint64_t gps_last_happy; extern void exti9_5_isr(void); +extern double gps_lat; +extern double gps_lon; +extern int gps_utc_diff; +extern int gps_wday; extern void gps_dispatch(void); extern int gps_init(void); extern int gps_almanac(void); @@ -112,12 +119,25 @@ extern void hexdump(void *_d, int len); /* bits.c */ extern void dump_bits(char *wot, uint8_t *bits); /* max7219.c */ -extern void max7219_write(int d, int h, int m, int s); extern void max7219_dispatch(void); -extern void max7219_init(int on); +extern void max7219_init(int on, int brightness); /* report.c */ extern void report_time(const char *src, EPOCH e, uint64_t abs, const char *info); /* sysclk.c */ extern void sysclk_event(void); extern uint64_t sysclk_extend(uint32_t now); extern void sysclk_dispatch(void); +/* cdcacm.c */ +extern ring_t cdcacm_rx_ring; +extern ring_t cdcacm_tx_ring; +extern const struct usb_interface_descriptor comm_iface; +extern const struct usb_interface_descriptor data_iface; +extern void cdcacm_tick(void); +extern void cdcacm_set_config(usbd_device *usbd_dev, uint16_t wValue); +extern void cdcacm_init(void); +extern void cdcacm_dispatch(void); +/* usb.c */ +extern uint8_t usbd_control_buffer[128]; +extern usbd_device *usb_device; +extern void otg_fs_isr(void); +extern void usb_init(void); diff --git a/app/report.c b/app/report.c index a7bd4db..f6c84d9 100644 --- a/app/report.c +++ b/app/report.c @@ -3,7 +3,7 @@ void report_time (const char *src, EPOCH e, uint64_t abs, const char *info) { - printf ("%s %08x%08x %08x%08x %s\r\n", + printf ("RT %s %08x%08x %08x%08x %s\r\n", src, (unsigned) (abs >> 32), (unsigned) (abs & 0xffffffff), diff --git a/app/ticker.c b/app/ticker.c index 2016058..bf7cf51 100644 --- a/app/ticker.c +++ b/app/ticker.c @@ -25,6 +25,7 @@ sys_tick_handler (void) ticks++; led_tick(); + cdcacm_tick(); slow++; @@ -54,8 +55,8 @@ ticker_init (void) { uint32_t v, w; - /*10MHz / 10000 -> 1ms */ - systick_set_reload (10000); + /*168MHz 1ms */ + systick_set_reload (168000); systick_set_clocksource (STK_CSR_CLKSOURCE_AHB); systick_counter_enable(); /* this done last */ diff --git a/app/time_fn.c b/app/time_fn.c index 87fb48f..3e58854 100644 --- a/app/time_fn.c +++ b/app/time_fn.c @@ -1,3 +1,4 @@ +#include #include "project.h" static int is_leap (unsigned year) @@ -17,7 +18,7 @@ static int is_leap (unsigned year) UTC time_epoch_to_utc (EPOCH epoch) { - UTC u; + UTC u = {0}; uint64_t day; unsigned y400, y100, y4; @@ -152,9 +153,6 @@ UTC time_epoch_to_utc (EPOCH epoch) return u; } - - - EPOCH time_utc_to_epoch (UTC u) { unsigned y400; @@ -221,7 +219,7 @@ void time_print_utc (const char *p, UTC u, const char *t) { 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%s %04d-%s-%02d %02d:%02d:%02d.%09d %s\r\n", p ? p : "", dname[u.wday], u.year, mname[u.month], u.mday, u.hour, u.minute, u.second, u.nanosecond , t ? t : ""); + printf ("%s%s %04d-%s-%02d %02d:%02d:%02d.%09d %s\r\n", p ? p : "", dname[u.wday], u.year, mname[u.month], u.mday, u.hour, u.minute, u.second, u.nanosecond, t ? t : ""); } void time_print_epoch (const char *p, EPOCH e, const char *t) @@ -230,3 +228,120 @@ void time_print_epoch (const char *p, EPOCH e, const char *t) time_print_utc (p, u, t); } + +double +time_utc_to_tjd (UTC u) +{ + unsigned y400; + unsigned y100; + unsigned y4; + + double ret; + unsigned jd; + + static int const mdays[] = + { 0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; + static int const lmdays[] = + { 0, 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 }; + + u.is_leap = is_leap (u.year); + + if (u.year < 100) + u.year += 2000; + + + if (!u.jday) { + if (u.is_leap) + u.jday = u.mday + lmdays[u.month]; + else + u.jday = u.mday + mdays[u.month]; + } + + u.year -= 1601; + y400 = u.year / 400; + u.year -= y400 * 400; + y100 = u.year / 100; + u.year -= y100 * 100; + y4 = u.year / 4; + u.year -= y4 * 4; + + jd = u.jday - 1; + jd += u.year * 365; + jd += y4 * 1461; + jd += y100 * 36524; + jd += y400 * 146097; + + + jd += 2305813; + jd -= 2451545; + + + + ret = (double) u.nanosecond; + ret /= 1000000000.; + ret += (double) u.second; + ret /= 60.; + ret += (double) u.minute; + ret /= 60.; + ret += (double) u.hour; + ret /= 24.; + + ret += .5; + + ret += (double) jd; + + return ret; +} + +double +time_utc_to_ra (UTC u) +{ + double tjd = time_utc_to_tjd (u); + double T = tjd / 36525.; + double theta0 = + 280.46061837 + (360.98564736629 * tjd) + (0.000387933 * T * T) - + (T * T * T / 38710000.0); + + return remainder (theta0, 360.); +} + + +ST +time_ra_to_st (double ra) +{ + ST ret; + unsigned i; + + while (ra < 0.) + ra += 360.; + + if (ra >= 360.0) + ra = remainder (ra, 360.); + + ra *= 240.0; + + i = (int) (floor (ra) + .5); + ra -= (double) i; + ra *= 1000000000.; + + ret.nanosecond = (unsigned) (ra + .5); + ret.second = i % 60; + i /= 60; + ret.minute = i % 60; + i /= 60; + ret.hour = i; + + return ret; +} + + + +ST time_utc_to_lst (UTC u, double lon) +{ + double ra; + + ra = time_utc_to_ra (u); + return time_ra_to_st (ra + lon); +} + + diff --git a/app/time_fn.h b/app/time_fn.h index 2409eeb..250c500 100644 --- a/app/time_fn.h +++ b/app/time_fn.h @@ -16,4 +16,12 @@ typedef struct { int64_t ns; } EPOCH; +typedef struct { + unsigned hour; + unsigned minute; + unsigned second; + unsigned nanosecond; +} ST; + + diff --git a/app/ubx.h b/app/ubx.h index 4874e92..87b7c0c 100644 --- a/app/ubx.h +++ b/app/ubx.h @@ -35,6 +35,13 @@ ubx_get_i32 (uint8_t *ptr, int32_t *v) } +static inline int +ubx_put_i8 (uint8_t *ptr, int8_t v) +{ + memcpy (ptr, &v, sizeof (v)); + return sizeof (v); +} + static inline int ubx_put_u8 (uint8_t *ptr, uint8_t v) { @@ -42,6 +49,14 @@ ubx_put_u8 (uint8_t *ptr, uint8_t v) return sizeof (v); } +static inline int +ubx_put_i16 (uint8_t *ptr, int16_t v) +{ + memcpy (ptr, &v, sizeof (v)); + return sizeof (v); +} + + static inline int ubx_put_u16 (uint8_t *ptr, uint16_t v) { -- cgit v1.2.3