summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorroot <root@lab.ourano.james.local>2021-02-25 19:12:38 +0000
committerroot <root@lab.ourano.james.local>2021-02-25 19:12:38 +0000
commit6d3a824e1cdae6e28146b7de380724b49488f3c2 (patch)
treeb8865608c9749e4251b316b74484b5151f2e683b
parent0548136a4c886830414fb575d9d0daa7f1a7d170 (diff)
downloadclock-6d3a824e1cdae6e28146b7de380724b49488f3c2.tar.gz
clock-6d3a824e1cdae6e28146b7de380724b49488f3c2.tar.bz2
clock-6d3a824e1cdae6e28146b7de380724b49488f3c2.zip
tim
-rw-r--r--app/Makefile9
-rw-r--r--app/dcf77.c8
-rw-r--r--app/gps.c368
-rw-r--r--app/lwip_glue.c8
-rw-r--r--app/main.c92
-rw-r--r--app/max7219.c111
-rw-r--r--app/msf.c6
-rw-r--r--app/pll.c8
-rw-r--r--app/project.h28
-rw-r--r--app/prototypes.h26
-rw-r--r--app/report.c2
-rw-r--r--app/ticker.c5
-rw-r--r--app/time_fn.c125
-rw-r--r--app/time_fn.h8
-rw-r--r--app/ubx.h15
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 <string.h>
#include <strings.h>
#include <inttypes.h>
+
+/* Core */
+#include <libopencm3/cm3/systick.h>
+#include <libopencm3/cm3/nvic.h>
+#include <libopencm3/cm3/cortex.h>
+#include <libopencm3/cm3/scs.h>
+#include <libopencm3/cm3/scb.h>
+/* SoC */
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/usart.h>
@@ -16,14 +24,18 @@
#include <libopencm3/stm32/exti.h>
#include <libopencm3/stm32/pwr.h>
#include <libopencm3/stm32/timer.h>
+#include <libopencm3/stm32/syscfg.h>
+#include <libopencm3/stm32/otg_common.h>
+#include <libopencm3/stm32/otg_fs.h>
+/* Drivers */
#include <libopencm3/ethernet/mac_stm32fxx7.h>
#include <libopencm3/ethernet/phy.h>
-#include <libopencm3/stm32/syscfg.h>
-#include <libopencm3/cm3/systick.h>
-#include <libopencm3/cm3/nvic.h>
-#include <libopencm3/cm3/cortex.h>
-#include <libopencm3/cm3/scs.h>
-#include <libopencm3/cm3/scb.h>
+#include <libopencm3/usb/usbd.h>
+#include <libopencm3/usb/cdc.h>
+#ifdef INCLUDE_DFU_INTERFACE
+#include <libopencm3/usb/dfu.h>
+#endif
+
#include <lwip/init.h>
@@ -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 <math.h>
#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
@@ -36,6 +36,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)
{
*ptr = v;
@@ -43,6 +50,14 @@ ubx_put_u8 (uint8_t *ptr, uint8_t 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)
{
memcpy (ptr, &v, sizeof (v));