From 74e577ac110513669a6d677842ceca4c5b1252ca Mon Sep 17 00:00:00 2001 From: fishsoupisgood Date: Sat, 4 May 2019 12:37:04 +0100 Subject: cut #1 --- app/gps.c | 316 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 277 insertions(+), 39 deletions(-) (limited to 'app/gps.c') diff --git a/app/gps.c b/app/gps.c index 39bb13f..9d5a992 100644 --- a/app/gps.c +++ b/app/gps.c @@ -1,12 +1,15 @@ #include "project.h" -#define PPS (GPIO2) -#define PPS_PORT GPIOD +#define PPS (GPIO9) +#define PPS_PORT GPIOC #define UBX_BUF_LEN 256 #define TIMEOUT 4000 + +static EPOCH next_sec; + static int ubx_ack = 0; static int ubx_ack_xfer = 0; @@ -24,22 +27,24 @@ static const int fish[] = { 1, 2, 3, 4, 5, 6, 7 }; static Event_ring gps_ring; +static char gps_info[60]; -void exti2_isr (void) + +void exti9_5_isr (void) { uint32_t now = SCS_DWT_CYCCNT; int v; v = !!gpio_get (PPS_PORT, PPS); - nvic_disable_irq (NVIC_EXTI2_IRQ); - exti_reset_request (EXTI2); + nvic_disable_irq (NVIC_EXTI9_5_IRQ); + exti_reset_request (EXTI9); gps_ring.events[gps_ring.tx_ptr].when = now; gps_ring.events[gps_ring.tx_ptr].value = v; gps_ring.tx_ptr = (gps_ring.tx_ptr + 1) & ERING_MASK; - nvic_enable_irq (NVIC_EXTI2_IRQ); + nvic_enable_irq (NVIC_EXTI9_5_IRQ); } @@ -48,19 +53,51 @@ void exti2_isr (void) static inline int ubx_recv_byte (uint8_t *v) { - return !ring_read_byte (&rx3_ring, v); + return !ring_read_byte (&rx1_ring, v); } static inline void ubx_send_byte (uint8_t v) { - usart3_queue (v); + usart1_queue (v); +} + +#define ALMANAC_SIZE + +static int ubx_recv_almanac (uint8_t *ptr, unsigned len) +{ + uint32_t sv, week; + uint32_t almanac[8]; + + ptr += ubx_get_u32 (ptr, &sv); + len -= 4; + ptr += ubx_get_u32 (ptr, &week); + len -= 4; + + if (len > sizeof (almanac)) + len = sizeof (almanac); + + bzero (almanac, sizeof (almanac)); + memcpy (almanac, ptr, len); + + printf (" Almanac: %2d %d %06x %06x %06x %06x %06x %06x %06x %06x\r\n", + (int) sv, (int) week, + (unsigned) almanac[0], + (unsigned) almanac[1], + (unsigned) almanac[2], + (unsigned) almanac[3], + (unsigned) almanac[4], + (unsigned) almanac[5], + (unsigned) almanac[6], + (unsigned) almanac[7]); + + return 0; } static int ubx_recv_nav_status (uint8_t *ptr, unsigned len) { - uint8_t gps_fix, flags; + uint8_t gps_fix, flags, fix_stat, flags2; uint32_t d; if ((!ptr) || (len != 16)) @@ -69,6 +106,8 @@ ubx_recv_nav_status (uint8_t *ptr, unsigned len) ptr += ubx_get_u32 (ptr, &d); //TOW ptr += ubx_get_u8 (ptr, &gps_fix); //fix type ptr += ubx_get_u8 (ptr, &flags); //fix type + ptr += ubx_get_u8 (ptr, &fix_stat); + ptr += ubx_get_u8 (ptr, &flags2); switch (gps_fix) { @@ -170,7 +209,7 @@ ubx_recv_utc (uint8_t *ptr, unsigned len) int32_t nano; uint32_t acc; uint16_t year; - uint8_t hour, min, sec, day, month; + uint8_t hour, min, sec, day, month, valid; uint32_t d; // char buf[40]; @@ -186,15 +225,31 @@ ubx_recv_utc (uint8_t *ptr, unsigned len) ptr += ubx_get_u8 (ptr, &hour); ptr += ubx_get_u8 (ptr, &min); ptr += ubx_get_u8 (ptr, &sec); + ptr += ubx_get_u8 (ptr, &valid); - printf ("GPS META-DATA %04d-%02d-%02d %02d:%02d:%02d Fix:%c%c TXCO %+8dE-12\r\n", - year, - month, - day, - hour, - min, - sec, +#if 0 + printf ("GPS META-DATA %04d-%02d-%02d %02d:%02d:%02d V:%02x Fix:%c%c TXCO %+8dE-12\r\n", + (int) year, + (int) month, + (int) day, + (int) hour, + (int) min, + (int) sec, + (unsigde) valid, fix, fix2, (int) freq); +#endif + + sprintf (gps_info, " %04d-%02d-%02d %02d:%02d:%02d V:%02x Fix:%c%c TXCO %+8dE-12", + + (int)year, + (int)month, + (int)day, + (int)hour, + (int)min, + (int)sec, + (unsigned) valid, fix, fix2, (int) freq); + + if (gps_happy > 3) { UTC u; @@ -213,6 +268,7 @@ ubx_recv_utc (uint8_t *ptr, unsigned len) gps_time = time_utc_to_epoch (u); + next_sec = gps_time; now = SCS_DWT_CYCCNT; abs = abs_extend (now); @@ -234,6 +290,60 @@ ubx_recv_utc (uint8_t *ptr, unsigned len) return 0; } + + +static int ubx_recv_nav_sbas (uint8_t *ptr, unsigned len) +{ + uint8_t prn, mode, service; + int8_t sys; + uint8_t n; + + ptr += 4; + + ptr += ubx_get_u8 (ptr, &prn); + ptr += ubx_get_u8 (ptr, &mode); + ptr += ubx_get_i8 (ptr, &sys); + ptr += ubx_get_u8 (ptr, &service); + + 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); + + while (n--) { + ptr += ubx_get_u8 (ptr, &prn); + ptr += 11; + printf ("GPS SBAS SV:%d\r\n", prn); + } + + return 0; +} + +static int ubx_recv_nav_sat (uint8_t *ptr, unsigned len) +{ + uint8_t gnssid, prn, cno, ver; + uint8_t n; + + ptr += 4; + + ptr += ubx_get_u8 (ptr, &ver); + ptr += ubx_get_u8 (ptr, &n); + ptr += 2; + + while (n--) { + ptr += ubx_get_u8 (ptr, &gnssid); + ptr += ubx_get_u8 (ptr, &prn); + ptr += ubx_get_u8 (ptr, &cno); + ptr += 9; + + printf ("GPS GNSS:%2d PRN:%3d CNO:%3d\r\n", gnssid, prn, cno); + } + + + return 0; +} + + static int ubx_recv_rinex (uint8_t *payload, unsigned len) { @@ -263,6 +373,14 @@ ubx_recv (uint8_t class, uint8_t id, uint8_t *payload, unsigned len) ubx_recv_clock_stats (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); hexdump (payload, len); @@ -280,6 +398,20 @@ ubx_recv (uint8_t class, uint8_t id, uint8_t *payload, unsigned len) break; + case 4: + switch (id) { + case 0x4: + break; + + default: + printf ("RX> %02x.%02x (%d bytes)\r\n", class, id, len); + hexdump (payload, len); + } + + break; + + + case 5: ubx_ack++; printf (" %s for %02x.%02x\r\n", id ? "ACK" : "NAK", payload[0], @@ -289,6 +421,10 @@ ubx_recv (uint8_t class, uint8_t id, uint8_t *payload, unsigned len) case 0x0b: switch (id) { + case 0x30: + ubx_recv_almanac (payload, len); + break; + case 0x50: printf ("xfer ack\r\n"); ubx_ack_xfer++; @@ -450,6 +586,9 @@ static void gps_pps_dispatch (void) v = gps_ring.events[gps_ring.rx_ptr].value; now = gps_ring.events[gps_ring.rx_ptr].when; + if (gps_happy) + led3_set (v); + gps_ring.rx_ptr = (gps_ring.rx_ptr + 1) & ERING_MASK; @@ -459,14 +598,16 @@ static void gps_pps_dispatch (void) - if (gps_happy) + if (gps_happy > 30) pll_dispatch (gps_last_happy, abs, "GPS"); e = pll_decompose (abs); //u = time_epoch_to_utc (e); - time_print_epoch ("GPS : ", e); + //time_print_epoch ("GPS : ", e, gps_info); + + report_time ("GPS", next_sec, abs, gps_info); } @@ -476,6 +617,7 @@ gps_dispatch (void) { ubx_dispatch_search (-1, -1, NULL); gps_pps_dispatch(); + } static void @@ -525,7 +667,7 @@ ubx_handshake (uint8_t class, uint8_t id, const void *payload, unsigned len) if (ticks > timeout) { printf ("GPS timeout resending packet\r\n"); - usart3_drain(); + usart1_drain(); ubx_send (class, id, payload, len); timeout = ticks + TIMEOUT; } @@ -546,7 +688,7 @@ ubx_handshake_xfer (uint8_t class, uint8_t id, const void *payload, uint32_t timeout; ubx_ack_xfer = 0; - // usart3_drain(); + // usart1_drain(); ubx_send (class, id, payload, len); @@ -557,7 +699,7 @@ ubx_handshake_xfer (uint8_t class, uint8_t id, const void *payload, if (ticks > timeout) { printf ("GPS timeout resending packet\r\n"); - // usart3_drain(); + // usart1_drain(); ubx_send (class, id, payload, len); timeout = ticks + TIMEOUT; } @@ -580,7 +722,7 @@ ubx_fetch (uint8_t class, uint8_t id, void *payload, unsigned len, { uint8_t *ret; - while (!ring_empty (&tx3_ring) || !ring_empty (&rx3_ring)) + while (!ring_empty (&tx1_ring) || !ring_empty (&rx1_ring)) gps_dispatch(); ubx_send (class, id, payload, len); @@ -591,6 +733,19 @@ ubx_fetch (uint8_t class, uint8_t id, void *payload, unsigned len, return ret; } +static int ubx_set_nav_rate (uint16_t ms) +{ + uint8_t buf[6], *ptr; + + ptr = buf; + + ptr += ubx_put_u16 (ptr, ms); + ptr += ubx_put_u16 (ptr, 1); /*1:1*/ + ptr += ubx_put_u16 (ptr, 0); /*UTC*/ + + return ubx_handshake (0x06, 0x08, buf, (unsigned) (ptr - buf)); +} + static int ubx_set_message_rate_port1 (uint8_t class, uint8_t id, uint8_t rate) { @@ -640,7 +795,7 @@ gps_set_ref (int ref_hz) ptr = buf; ptr += ubx_put_u8 (ptr, 0); //timepluse 1 - ptr += ubx_put_u8 (ptr, 0); //reserved + 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 @@ -650,8 +805,8 @@ gps_set_ref (int ref_hz) 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, 500000 / ref_hz); //pulse width unlocked/us - ptr += ubx_put_u32 (ptr, 500000 / ref_hz); //pulse width locked/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_i32 (ptr, 0); // ? delay @@ -660,7 +815,7 @@ gps_set_ref (int ref_hz) ptr += ubx_put_u32 (ptr, 0xf7); #else /*Same numbers for locked/unlocked*/ - ptr += ubx_put_u32 (ptr, 0xf3); + ptr += ubx_put_u32 (ptr, 0xf7); #endif @@ -677,15 +832,16 @@ gps_init (void) unsigned len; // uint16_t u2; - usart3_drain(); + usart1_drain(); - while (!ring_empty (&tx3_ring) || !ring_empty (&rx3_ring)) + while (!ring_empty (&tx1_ring) || !ring_empty (&rx1_ring)) gps_dispatch(); printf ("Testing GNSS...\r\n"); ubx_handshake (0x06, 0x00, NULL, 0); printf ("GNSS there\r\n"); + // Set up port ptr = buf; ptr += ubx_put_u8 (ptr, 1); //uart1 @@ -693,7 +849,7 @@ gps_init (void) ptr += ubx_put_u16 (ptr, 0x0); //flow control off ptr += ubx_put_u32 (ptr, 0x8c0); //no parity, 8 bits ptr += ubx_put_u32 (ptr, 9600); // baudrate - ptr += ubx_put_u16 (ptr, 0x7); // receive RTCM, NMEA, UBX + ptr += ubx_put_u16 (ptr, 0x3); // receive NMEA, UBX ptr += ubx_put_u16 (ptr, 0x1); // transmit UBX ptr += ubx_put_u16 (ptr, 0x0); // no txtimeout ptr += ubx_put_u16 (ptr, 0x0); // reserved @@ -701,7 +857,7 @@ gps_init (void) printf ("configured GNSS protocol\r\n"); -#if 1 +#if 0 ptr = buf; ptr += ubx_put_u16 (ptr, 0x14); ptr += ubx_put_u16 (ptr, 0x00); @@ -749,17 +905,30 @@ gps_init (void) printf ("configured GNSS data\r\n"); + gps_set_ref (1); + ubx_fetch (0x06, 0x31, NULL, 0, &len); printf ("configured GNSS 6.31\r\n"); + + ubx_set_nav_rate (1000); + #if 1 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 (0x03, 0x0a, 0); - //ubx_set_message_rate_port1 (0x03, 0x10, 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); + printf ("GNSS ready\r\n"); #else ubx_set_message_rate_port1 (0x01, 0x03, 0); @@ -771,7 +940,7 @@ gps_init (void) printf ("GNSS ready\r\n"); #endif -#if 1 +#if 0 ptr = buf; ptr += ubx_put_u8 (ptr, 0x1); ptr += ubx_put_u8 (ptr, 0x7); @@ -791,16 +960,16 @@ gps_init (void) MAP_INPUT (PPS); - exti_select_source (EXTI2, PPS_PORT); - exti_set_trigger (EXTI2, EXTI_TRIGGER_BOTH); - exti_enable_request (EXTI2); - nvic_enable_irq (NVIC_EXTI2_IRQ); + exti_select_source (EXTI9, PPS_PORT); + exti_set_trigger (EXTI9, EXTI_TRIGGER_BOTH); + exti_enable_request (EXTI9); + nvic_enable_irq (NVIC_EXTI9_5_IRQ); return 0; } -#define ALMANAC_LUMP 128 +#define ALMANAC_LUMP 64 int gps_almanac (void) @@ -831,6 +1000,75 @@ gps_almanac (void) return 0; } +void gps_dump_almanac (void) +{ + ubx_send (0xb, 0x30, NULL, 0); +} + + +#if 1 +int gps_bs (void) +{ + uint32_t now = SCS_DWT_CYCCNT; + uint64_t abs = abs_extend (now); + EPOCH e = pll_decompose (abs); + UTC u = time_epoch_to_utc (e); + + uint8_t buf[80], *ptr; + int ret; + + ptr = buf; + + ptr += ubx_put_u32 (ptr, 391706007); /*19 sleaford st*/ + ptr += ubx_put_u32 (ptr, 955140); + ptr += ubx_put_u32 (ptr, 501672842); + ptr += ubx_put_u32 (ptr, 100000); /*1km std dev*/ + + ptr += ubx_put_u16 (ptr, 0); /*no time mark*/ + + ptr += ubx_put_u16 (ptr, (u.year - 2000) * 100 + u.month); + ptr += ubx_put_u32 (ptr, (u.mday * 1000000) + (u.hour * 10000) + (u.minute * 100) + u.second); + ptr += ubx_put_u32 (ptr, u.nanosecond); + + ptr += ubx_put_u32 (ptr, 2000); /* time good to 2s */ + ptr += ubx_put_u32 (ptr, 0); + + ptr += ubx_put_u32 (ptr, 0); + ptr += ubx_put_u32 (ptr, 0); + + ptr += ubx_put_u32 (ptr, 0x403); + + printf ("Bootstrapping GPS\r\n"); + + hexdump (buf, (unsigned) (ptr - buf)); + + ubx_send (0x0b, 0x01, buf, (unsigned) (ptr - buf)); + + + ret = 0; + + + /* + 00000: 97 f5 58 17 + 04 93 0e 00 + 8a eb e6 1d + a0 86 01 00 + 00010: 00 00 + 6f 07 19/03 + 03 cb 06 01 /17 22:24:03 + 65 ca af 02 45075045ns + + d0 07 00 00 2000ms + 00020: 00 00 00 00 0ns + 00 00 00 00 + 00 00 00 00 + 03 04 00 00 + */ + + return ret; +} + +#endif void @@ -846,7 +1084,7 @@ gps_reset (void) ubx_cfg_rst (REPHEMERIDIES | RALMANAC | RPOS | RRTC); delay_ms (1000); - usart3_drain(); + usart1_drain(); printf ("Testing GNSS...\r\n"); -- cgit v1.2.3