Merge branch 'micropeak-1.1'
[fw/altos] / src / drivers / ao_gps_skytraq.c
index 050573e877282012acf1776668396f980822bfdf..d2f67e6b6947b1f9cd4c8e1c87fc13a018eb23b7 100644 (file)
 #include "ao.h"
 #endif
 
+#ifndef ao_gps_getchar
+#define ao_gps_getchar ao_serial1_getchar
+#define ao_gps_fifo    ao_serial1_rx_fifo
+#endif
+
+#ifndef ao_gps_putchar
+#define ao_gps_putchar ao_serial1_putchar
+#endif
+
+#ifndef ao_gps_set_speed
+#define ao_gps_set_speed       ao_serial1_set_speed
+#endif
+
 __xdata uint8_t ao_gps_mutex;
 static __data char ao_gps_char;
 static __data uint8_t ao_gps_cksum;
@@ -68,7 +81,7 @@ ao_gps_lexchar(void)
        if (ao_gps_error)
                c = '\n';
        else
-               c = ao_serial_getchar();
+               c = ao_gps_getchar();
        ao_gps_cksum ^= c;
        ao_gps_char = c;
 }
@@ -402,7 +415,7 @@ ao_skytraq_sendbytes(__code uint8_t *b, uint8_t l)
                uint8_t c = *b++;
                if (c == 0xa0)
                        ao_delay(AO_MS_TO_TICKS(500));
-               ao_serial_putchar(c);
+               ao_gps_putchar(c);
        }
 }
 
@@ -441,10 +454,12 @@ ao_gps_nmea_parse(void)
        }
 }
 
+static uint8_t ao_gps_updating;
+
 void
 ao_gps(void) __reentrant
 {
-       ao_serial_set_speed(AO_SERIAL_SPEED_9600);
+       ao_gps_set_speed(AO_SERIAL_SPEED_9600);
 
        /* give skytraq time to boot in case of cold start */
        ao_delay(AO_MS_TO_TICKS(2000));
@@ -453,9 +468,16 @@ ao_gps(void) __reentrant
 
        for (;;) {
                /* Locate the begining of the next record */
-               if (ao_serial_getchar() == '$') {
+               if (ao_gps_getchar() == '$') {
                        ao_gps_nmea_parse();
                }
+#ifndef AO_GPS_TEST
+               while (ao_gps_updating) {
+                       ao_usb_putchar(ao_gps_getchar());
+                       if (ao_fifo_empty(ao_gps_fifo))
+                               flush();
+               }
+#endif
        }
 }
 
@@ -468,7 +490,7 @@ gps_dump(void) __reentrant
        ao_mutex_get(&ao_gps_mutex);
        printf ("Date: %02d/%02d/%02d\n", ao_gps_data.year, ao_gps_data.month, ao_gps_data.day);
        printf ("Time: %02d:%02d:%02d\n", ao_gps_data.hour, ao_gps_data.minute, ao_gps_data.second);
-       printf ("Lat/Lon: %ld %ld\n", ao_gps_data.latitude, ao_gps_data.longitude);
+       printf ("Lat/Lon: %ld %ld\n", (long) ao_gps_data.latitude, (long) ao_gps_data.longitude);
        printf ("Alt: %d\n", ao_gps_data.altitude);
        printf ("Flags: 0x%x\n", ao_gps_data.flags);
        printf ("Sats: %d", ao_gps_tracking_data.channels);
@@ -480,8 +502,38 @@ gps_dump(void) __reentrant
        ao_mutex_put(&ao_gps_mutex);
 }
 
+static __code uint8_t ao_gps_115200[] = {
+       SKYTRAQ_MSG_3(5,0,5,0)  /* Set to 115200 baud */
+};
+
+static void
+ao_gps_set_speed_delay(uint8_t speed) {
+       ao_delay(AO_MS_TO_TICKS(500));
+       ao_gps_set_speed(speed);
+       ao_delay(AO_MS_TO_TICKS(500));
+}
+
+static void
+gps_update(void) __reentrant
+{
+       ao_gps_updating = 1;
+       ao_task_minimize_latency = 1;
+#if HAS_ADC
+       ao_timer_set_adc_interval(0);
+#endif
+       ao_skytraq_sendstruct(ao_gps_115200);
+       ao_gps_set_speed_delay(AO_SERIAL_SPEED_4800);
+       ao_skytraq_sendstruct(ao_gps_115200);
+       ao_gps_set_speed_delay(AO_SERIAL_SPEED_115200);
+
+       /* It's a binary protocol; abandon attempts to escape */
+       for (;;)
+               ao_gps_putchar(ao_usb_getchar());
+}
+
 __code struct ao_cmds ao_gps_cmds[] = {
        { gps_dump,     "g\0Display GPS" },
+       { gps_update,   "U\0Update GPS firmware" },
        { 0, NULL },
 };