__xdata uint8_t ao_gps_mutex;
__xdata struct ao_gps_data ao_gps_data;
+__xdata struct ao_gps_tracking_data ao_gps_tracking_data;
-#undef AO_GPS_4800
-
-#ifdef AO_GPS_4800
-static const char ao_gps_set_nmea[] = "$PSRF100,0,57600,8,1,0*37\r\n";
-#else
-static const char ao_gps_set_nmea[] = "$PSRF100,0,4800,8,1,0*0F\r\n";
-#endif
+static const char ao_gps_set_nmea[] = "\r\n$PSRF100,0,57600,8,1,0*37\r\n";
const char ao_gps_config[] = {
- 0xa0, 0xa2, 0x00, 0x19, /* length: 25 bytes */
- 128, /* Initialize Data Source */
- 0, 0, 0, 0, /* ECEF X */
- 0, 0, 0, 0, /* ECEF Y */
- 0, 0, 0, 0, /* ECEF Z */
- 0, 0, 0, 0, /* Clock Drift */
- 0, 0, 0, 0, /* Time of Week */
- 0, 0, /* Week Number */
- 0, /* Channels */
- 0xc6, /* Clear user data, RTC not accurate, Clear history, clear ephemeris */
- 0x01, 0x46, 0xb0, 0xb3,
0xa0, 0xa2, 0x00, 0x0e, /* length: 14 bytes */
136, /* mode control */
0, 0, /* reserved */
- 4, /* degraded mode (disabled) */
+ 0, /* degraded mode (allow 1-SV navigation) */
0, 0, /* reserved */
0, 0, /* user specified altitude */
2, /* alt hold mode (disabled, require 3d fixes) */
0, /* alt hold source (use last computed altitude) */
0, /* reserved */
- 0, /* Degraded time out (disabled) */
- 0, /* Dead Reckoning time out (disabled) */
+ 10, /* Degraded time out (10 sec) */
+ 10, /* Dead Reckoning time out (10 sec) */
0, /* Track smoothing (disabled) */
0x00, 0x8e, 0xb0, 0xb3,
static __xdata struct sirf_geodetic_nav_data ao_sirf_data;
+struct sirf_measured_sat_data {
+ uint8_t svid;
+ uint16_t state;
+ uint8_t c_n_1;
+};
+
+struct sirf_measured_tracker_data {
+ int16_t gps_week;
+ uint32_t gps_tow;
+ uint8_t channels;
+ struct sirf_measured_sat_data sats[12];
+};
+
+static __xdata struct sirf_measured_tracker_data ao_sirf_tracker_data;
+
static __pdata uint16_t ao_sirf_cksum;
static __pdata uint16_t ao_sirf_len;
return c;
}
+static char __xdata *sirf_target;
+
static void sirf_u16(uint8_t offset)
{
- uint16_t __xdata *ptr = (uint16_t __xdata *) (((char __xdata *) &ao_sirf_data) + offset);
+ uint16_t __xdata *ptr = (uint16_t __xdata *) (sirf_target + offset);
uint16_t val;
val = data_byte() << 8;
static void sirf_u8(uint8_t offset)
{
- uint8_t __xdata *ptr = (uint8_t __xdata *) (((char __xdata *) &ao_sirf_data) + offset);
+ uint8_t __xdata *ptr = (uint8_t __xdata *) (sirf_target + offset);
uint8_t val;
val = data_byte ();
*ptr = val;
}
-static void sirf_u32(uint8_t offset)
+static void sirf_u32(uint8_t offset) __reentrant
{
- uint32_t __xdata *ptr = (uint32_t __xdata *) (((char __xdata *) &ao_sirf_data) + offset);
+ uint32_t __xdata *ptr = (uint32_t __xdata *) (sirf_target + offset);
uint32_t val;
val = ((uint32_t) data_byte ()) << 24;
#define SIRF_U8 2
#define SIRF_U16 3
#define SIRF_U32 4
+#define SIRF_U8X10 5
struct sirf_packet_parse {
uint8_t type;
uint8_t offset;
};
+static void
+ao_sirf_parse(void __xdata *target, const struct sirf_packet_parse *parse) __reentrant
+{
+ uint8_t i, offset, j;
+
+ sirf_target = target;
+ for (i = 0; ; i++) {
+ offset = parse[i].offset;
+ switch (parse[i].type) {
+ case SIRF_END:
+ return;
+ case SIRF_DISCARD:
+ sirf_discard(offset);
+ break;
+ case SIRF_U8:
+ sirf_u8(offset);
+ break;
+ case SIRF_U16:
+ sirf_u16(offset);
+ break;
+ case SIRF_U32:
+ sirf_u32(offset);
+ break;
+ case SIRF_U8X10:
+ for (j = 10; j--;)
+ sirf_u8(offset++);
+ break;
+ }
+ }
+}
+
static const struct sirf_packet_parse geodetic_nav_data_packet[] = {
{ SIRF_DISCARD, 2 }, /* 1 nav valid */
{ SIRF_U16, offsetof(struct sirf_geodetic_nav_data, nav_type) }, /* 3 */
};
static void
-ao_sirf_parse_41(void)
+ao_sirf_parse_41(void) __reentrant
{
- uint8_t i, offset;
+ ao_sirf_parse(&ao_sirf_data, geodetic_nav_data_packet);
+}
- for (i = 0; ; i++) {
- offset = geodetic_nav_data_packet[i].offset;
- switch (geodetic_nav_data_packet[i].type) {
- case SIRF_END:
- return;
- case SIRF_DISCARD:
- sirf_discard(offset);
- break;
- case SIRF_U8:
- sirf_u8(offset);
- break;
- case SIRF_U16:
- sirf_u16(offset);
- break;
- case SIRF_U32:
- sirf_u32(offset);
- break;
- }
- }
+static const struct sirf_packet_parse measured_tracker_data_packet[] = {
+ { SIRF_U16, offsetof (struct sirf_measured_tracker_data, gps_week) }, /* 1 week */
+ { SIRF_U32, offsetof (struct sirf_measured_tracker_data, gps_tow) }, /* 3 time of week */
+ { SIRF_U8, offsetof (struct sirf_measured_tracker_data, channels) }, /* 7 channels */
+ { SIRF_END, 0 },
+};
+
+static const struct sirf_packet_parse measured_sat_data_packet[] = {
+ { SIRF_U8, offsetof (struct sirf_measured_sat_data, svid) }, /* 0 SV id */
+ { SIRF_DISCARD, 2 }, /* 1 azimuth, 2 elevation */
+ { SIRF_U16, offsetof (struct sirf_measured_sat_data, state) }, /* 2 state */
+ { SIRF_U8, offsetof (struct sirf_measured_sat_data, c_n_1) }, /* C/N0 1 */
+ { SIRF_DISCARD, 9 }, /* C/N0 2-10 */
+ { SIRF_END, 0 },
+};
+
+static void
+ao_sirf_parse_4(void) __reentrant
+{
+ uint8_t i;
+ ao_sirf_parse(&ao_sirf_tracker_data, measured_tracker_data_packet);
+ for (i = 0; i < 12; i++)
+ ao_sirf_parse(&ao_sirf_tracker_data.sats[i], measured_sat_data_packet);
}
static void
ao_gps_setup(void) __reentrant
{
uint8_t i, k;
-#ifdef AO_GPS_4800
ao_serial_set_speed(AO_SERIAL_SPEED_4800);
-#endif
for (i = 0; i < 64; i++)
ao_serial_putchar(0x00);
for (k = 0; k < 3; k++)
for (i = 0; i < sizeof (ao_gps_set_nmea); i++)
ao_serial_putchar(ao_gps_set_nmea[i]);
-#ifdef AO_GPS_4800
ao_serial_set_speed(AO_SERIAL_SPEED_57600);
-#endif
for (i = 0; i < 64; i++)
ao_serial_putchar(0x00);
}
static const uint8_t sirf_disable[] = {
2,
- 4,
9,
10,
27,
for (i = 0; i < sizeof (sirf_disable); i++)
ao_sirf_set_message_rate(sirf_disable[i], 0);
ao_sirf_set_message_rate(41, 1);
+ ao_sirf_set_message_rate(4, 1);
}
for (;;) {
/* Locate the begining of the next record */
break;
ao_sirf_parse_41();
break;
+ case 4:
+ if (ao_sirf_len < 187)
+ break;
+ ao_sirf_parse_4();
+ break;
}
if (ao_sirf_len != 0)
continue;
ao_mutex_put(&ao_gps_mutex);
ao_wakeup(&ao_gps_data);
break;
+ case 4:
+ ao_mutex_get(&ao_gps_mutex);
+ ao_gps_tracking_data.channels = ao_sirf_tracker_data.channels;
+ for (i = 0; i < 12; i++) {
+ ao_gps_tracking_data.sats[i].svid = ao_sirf_tracker_data.sats[i].svid;
+ ao_gps_tracking_data.sats[i].state = (uint8_t) ao_sirf_tracker_data.sats[i].state;
+ ao_gps_tracking_data.sats[i].c_n_1 = ao_sirf_tracker_data.sats[i].c_n_1;
+ }
+ ao_mutex_put(&ao_gps_mutex);
+ ao_wakeup(&ao_gps_tracking_data);
+ break;
}
}
}
{
ao_mutex_get(&ao_gps_mutex);
ao_gps_print(&ao_gps_data);
+ putchar('\n');
+ ao_gps_tracking_print(&ao_gps_tracking_data);
+ putchar('\n');
ao_mutex_put(&ao_gps_mutex);
}