summaryrefslogtreecommitdiff
path: root/driver_sirf.c
diff options
context:
space:
mode:
authorGary E. Miller <gem@rellim.com>2010-04-14 18:57:06 -0700
committerGary E. Miller <gem@rellim.com>2010-04-14 18:57:06 -0700
commit6b88596e55ce4068346bcd7b94ded4e04e6a6cea (patch)
tree8810b5c3c83fc19557c509ed0a585364f94b5cf9 /driver_sirf.c
parentb08ff6f8132a25173660706abe0be2d1f2b30cf7 (diff)
downloadgpsd-6b88596e55ce4068346bcd7b94ded4e04e6a6cea.tar.gz
driver_sirf.c 50BPS parity check seems to work. No wonder there are
so many parity bits, the data stream is a mess.
Diffstat (limited to 'driver_sirf.c')
-rw-r--r--driver_sirf.c43
1 files changed, 36 insertions, 7 deletions
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;
}