__xdata uint8_t ao_gps_mutex;
__xdata struct ao_gps_data ao_gps_data;
+__xdata struct ao_gps_tracking_data ao_gps_tracking_data;
-const char ao_gps_set_binary[] = {
- '$', 'P', 'S', 'R', 'F', '1', '0', '0', ',', '0', ',',
- '9', '6', '0', '0', ',', '8', ',', '1', ',', '0', '*',
- '0', 'C', '\r','\n',
-
- 0xa0, 0xa2, 0x00, 0x09, /* length 9 bytes */
- 134, /* Set binary serial port */
- 0, 0, 0x25, 0x80, /* 9600 baud */
- 8, /* data bits */
- 1, /* stop bits */
- 0, /* parity */
- 0, /* pad */
- 0x01, 0x34, 0xb0, 0xb3,
-};
+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, 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,
+ 0xa0, 0xa2, 0x00, 0x08, /* length: 8 bytes */
+ 166, /* Set message rate */
+ 2, /* enable/disable all messages */
+ 0, /* message id (ignored) */
+ 0, /* update rate (0 = disable) */
+ 0, 0, 0, 0, /* reserved */
+ 0x00, 0xa8, 0xb0, 0xb3,
+
0xa0, 0xa2, 0x00, 0x02, /* length: 2 bytes */
143, /* static navigation */
0, /* disable */
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);
}
-void
+static void
ao_gps_setup(void) __reentrant
{
- uint8_t i, j;
- for (j = 0; j < 2; j++) {
-#ifdef AO_GPS_TEST
- ao_serial_set_speed(j);
-#endif
- for (i = 255; i != 0; i--)
- ao_serial_putchar(0);
-
- for (i = 0; i < sizeof (ao_gps_set_binary); i++)
- ao_serial_putchar(ao_gps_set_binary[i]);
- }
+ uint8_t i, k;
+ ao_serial_set_speed(AO_SERIAL_SPEED_4800);
+ 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]);
+ ao_serial_set_speed(AO_SERIAL_SPEED_57600);
+ for (i = 0; i < 64; i++)
+ ao_serial_putchar(0x00);
}
static const char ao_gps_set_message_rate[] = {
0xa0, 0xa2, 0x00, 0x08,
166,
0,
-#define SET_MESSAGE_RATE_ID 6
-#define SET_MESSAGE_RATE 7
-
};
void
static const uint8_t sirf_disable[] = {
2,
- 4,
9,
10,
27,
50,
52,
- 4,
};
void
ao_gps(void) __reentrant
{
- uint8_t i;
+ uint8_t i, k;
uint16_t cksum;
- for (i = 0; i < sizeof (ao_gps_config); i++)
- ao_serial_putchar(ao_gps_config[i]);
- 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_gps_setup();
+ for (k = 0; k < 5; k++)
+ {
+ for (i = 0; i < sizeof (ao_gps_config); i++)
+ ao_serial_putchar(ao_gps_config[i]);
+ 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 */
- while (ao_sirf_byte() != 0xa0)
+ while (ao_sirf_byte() != (uint8_t) 0xa0)
;
- if (ao_sirf_byte() != 0xa2)
+ if (ao_sirf_byte() != (uint8_t) 0xa2)
continue;
/* Length */
/* message ID */
i = data_byte (); /* 0 */
- printf ("message %d len %d\n", i, ao_sirf_len);
switch (i) {
case 41:
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;
cksum |= ao_sirf_byte();
if (ao_sirf_cksum != cksum)
continue;
- if (ao_sirf_byte() != 0xb0)
+ if (ao_sirf_byte() != (uint8_t) 0xb0)
continue;
- if (ao_sirf_byte() != 0xb3)
+ if (ao_sirf_byte() != (uint8_t) 0xb3)
continue;
switch (i) {
ao_gps_data.hour = ao_sirf_data.utc_hour;
ao_gps_data.minute = ao_sirf_data.utc_minute;
ao_gps_data.second = ao_sirf_data.utc_second / 1000;
- ao_gps_data.flags = (ao_sirf_data.num_sv << AO_GPS_NUM_SAT_SHIFT) & AO_GPS_NUM_SAT_MASK;
+ ao_gps_data.flags = ((ao_sirf_data.num_sv << AO_GPS_NUM_SAT_SHIFT) & AO_GPS_NUM_SAT_MASK) | AO_GPS_RUNNING;
if ((ao_sirf_data.nav_type & NAV_TYPE_GPS_FIX_TYPE_MASK) >= NAV_TYPE_4_SV_KF)
ao_gps_data.flags |= AO_GPS_VALID;
ao_gps_data.latitude = ao_sirf_data.lat;
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);
}