From 6b88596e55ce4068346bcd7b94ded4e04e6a6cea Mon Sep 17 00:00:00 2001 From: "Gary E. Miller" Date: Wed, 14 Apr 2010 18:57:06 -0700 Subject: driver_sirf.c 50BPS parity check seems to work. No wonder there are so many parity bits, the data stream is a mess. --- driver_sirf.c | 43 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 7 deletions(-) (limited to 'driver_sirf.c') diff --git a/driver_sirf.c b/driver_sirf.c index 2cf8b6b0..c8ca0020 100644 --- a/driver_sirf.c +++ b/driver_sirf.c @@ -432,6 +432,32 @@ static gps_mask_t sirf_msg_swversion(struct gps_device_t *session, } #endif /* ALLOW_RECONFIGURE */ +#ifdef __UNUSED__ +static unsigned int isgps_parity1( unsigned int value ) +{ + unsigned int result; + + /* D30 is XOR of D30* d3 d5 d6 d8 d9 d10 d11 d13 d15 d19 d22 d23 d24 */ + result ^= ((value >> 31) & 1); /* D29* to D30 */ + result ^= ((value >> 27) & 1); /* d3 to D30 */ + result ^= ((value >> 25) & 1); /* d5 to D30 */ + result ^= ((value >> 24) & 1); /* d6 to D30 */ + result ^= ((value >> 22) & 1); /* d8 to D30 */ + result ^= ((value >> 21) & 1); /* d9 to D30 */ + result ^= ((value >> 20) & 1); /* d10 to D30 */ + result ^= ((value >> 19) & 1); /* d11 to D30 */ + result ^= ((value >> 17) & 1); /* d13 to D30 */ + result ^= ((value >> 15) & 1); /* d15 to D30 */ + result ^= ((value >> 11) & 1); /* d19 to D30 */ + result ^= ((value >> 8) & 1); /* d22 to D30 */ + result ^= ((value >> 7) & 1); /* d23 to D30 */ + result ^= ((value >> 6) & 1); /* d24 to D30 */ + + return result; + +} +#endif + static gps_mask_t sirf_msg_navdata(struct gps_device_t *session, unsigned char *buf, size_t len) { @@ -455,17 +481,20 @@ static gps_mask_t sirf_msg_navdata(struct gps_device_t *session, * 2 bits are the bottom two parity bits from the previous word. Mask and * shift these away to leave us with 3 data bytes per word */ + /* gotta do the first word by hand, D29* and D30* seem missing */ words[0] = ((unsigned int)getbeul(buf, 3) & 0x3fffffff) >> 6; preamble = words[0] >> 16; if (preamble == 0x8b) { preamble ^= 0xff; - words[0] ^= 0xffffC0; + words[0] ^= 0x3fffC0; } parity1 = parity9 = 0; for (i = 1; i < 10; i++) { int invert; - words[i] = (unsigned int)getbeul(buf, 4 * i + 3); + unsigned int word; + word = (unsigned int)getbeul(buf, 4 * i + 3); + words[i] = word; switch (i) { case 1: parity1 = words[1] & 0x3; @@ -478,14 +507,14 @@ static gps_mask_t sirf_msg_navdata(struct gps_device_t *session, invert = (words[i] & 0x40000000) ? 1 : 0; /* inverted data, invert it back */ if (invert) { - words[i] ^= 0xffffffC0; + words[i] ^= 0x3fffffC0; } - parity = isgps_parity( getbeul(buf, 4 * i + 3)); - if ( parity != (getbeul(buf, 4 * i + 3) & 0x3f) ) { + parity = isgps_parity( words[i] ) ; + if ( parity != (words[i] & 0x3F) ) { gpsd_report(LOG_WARN, "SiRF: 50BPS parity fail words[%d] 0x%x != 0x%x\n", i, - parity, ( getbeul(buf, 4 * i + 3) & 0x3f)); - //return 0; + parity, ( words[i] & 0x1)); + return 0; } words[i] = (words[i] & 0x3fffffff) >> 6; } -- cgit v1.2.1