@@ -48,10 +48,70 @@ boolean SFE_UBLOX_GPS::begin(TwoWire &wirePort, uint8_t deviceAddress)
48
48
// _i2cPort->begin();
49
49
50
50
_gpsI2Caddress = deviceAddress; // Store the I2C address from user
51
-
51
+
52
+ return (isConnected ());
53
+ }
54
+
55
+ // Initialize the Serial port
56
+ boolean SFE_UBLOX_GPS::begin (Stream &serialPort)
57
+ {
58
+ commType = COMM_TYPE_SERIAL;
59
+ _serialPort = &serialPort; // Grab which port the user wants us to use
60
+
52
61
return (isConnected ());
53
62
}
54
63
64
+ void SFE_UBLOX_GPS::factoryReset () {
65
+ // Copy default settings to permanent
66
+ packetCfg.cls = UBX_CLASS_CFG;
67
+ packetCfg.id = UBX_CFG_CFG;
68
+ packetCfg.len = 13 ;
69
+ packetCfg.startingSpot = 0 ;
70
+ for (int i=0 ; i<4 ; i++) {
71
+ payloadCfg[0 +i] = 0xff ; // clear mask: copy default config to permanent config
72
+ payloadCfg[4 +i] = 0x00 ; // save mask: don't save current to permanent
73
+ payloadCfg[8 +i] = 0x00 ; // load mask: don't copy permanent config to current
74
+ }
75
+ payloadCfg[12 ] = 0xff ; // all forms of permanent memory
76
+ sendCommand (packetCfg, 0 ); // don't expect ACK
77
+
78
+ // Issue hard reset
79
+ packetCfg.cls = UBX_CLASS_CFG;
80
+ packetCfg.id = UBX_CFG_RST;
81
+ packetCfg.len = 4 ;
82
+ packetCfg.startingSpot = 0 ;
83
+ payloadCfg[0 ] = 0xff ; // cold start
84
+ payloadCfg[1 ] = 0xff ; // cold start
85
+ payloadCfg[2 ] = 0 ; // 0=HW reset
86
+ payloadCfg[3 ] = 0 ; // reserved
87
+ sendCommand (packetCfg, 0 ); // don't expect ACK
88
+ }
89
+
90
+ // Changes the serial baud rate of the Ublox module, can't return success/fail 'cause ACK from modem
91
+ // is lost due to baud rate change
92
+ void SFE_UBLOX_GPS::setSerialRate (uint32_t baudrate, uint16_t maxWait) {
93
+ // Get the current config values for the UART port
94
+ getPortSettings (COM_PORT_UART1, maxWait); // This will load the payloadCfg array with current port settings
95
+ Serial.printf (" Current baud rate: %d\n " ,
96
+ ((uint32_t )payloadCfg[10 ]<<16 ) | ((uint32_t )payloadCfg[9 ]<<8 ) | payloadCfg[8 ]);
97
+
98
+ packetCfg.cls = UBX_CLASS_CFG;
99
+ packetCfg.id = UBX_CFG_PRT;
100
+ packetCfg.len = 20 ;
101
+ packetCfg.startingSpot = 0 ;
102
+
103
+ // payloadCfg is now loaded with current bytes. Change only the ones we need to
104
+ payloadCfg[8 ] = baudrate;
105
+ payloadCfg[9 ] = baudrate>>8 ;
106
+ payloadCfg[10 ] = baudrate>>16 ;
107
+ payloadCfg[11 ] = baudrate>>24 ;
108
+ Serial.printf (" Next baud rate: %d=0x%x\n " ,
109
+ ((uint32_t )payloadCfg[10 ]<<16 ) | ((uint32_t )payloadCfg[9 ]<<8 ) | payloadCfg[8 ],
110
+ ((uint32_t )payloadCfg[10 ]<<16 ) | ((uint32_t )payloadCfg[9 ]<<8 ) | payloadCfg[8 ]);
111
+
112
+ sendCommand (packetCfg);
113
+ }
114
+
55
115
// Changes the I2C address that the Ublox module responds to
56
116
// 0x42 is the default but can be changed with this command
57
117
boolean SFE_UBLOX_GPS::setI2CAddress (uint8_t deviceAddress, uint16_t maxWait)
@@ -89,6 +149,7 @@ boolean SFE_UBLOX_GPS::checkUblox()
89
149
checkUbloxI2C ();
90
150
else if (commType == COMM_TYPE_SERIAL)
91
151
checkUbloxSerial ();
152
+ return false ;
92
153
}
93
154
94
155
// Polls I2C for data, passing any new bytes to process()
@@ -150,12 +211,14 @@ boolean SFE_UBLOX_GPS::checkUbloxI2C()
150
211
151
212
} // end checkUbloxI2C()
152
213
153
- // Polls Serial for data, passing any new bytes to process()
154
- // Times out after given amount of time
214
+ // Checks Serial for data, passing any new bytes to process()
155
215
boolean SFE_UBLOX_GPS::checkUbloxSerial ()
156
216
{
157
- // Todo
158
- return (true );
217
+ while (_serialPort->available ())
218
+ {
219
+ process (_serialPort->read ());
220
+ }
221
+ return (true );
159
222
160
223
} // end checkUbloxSerial()
161
224
@@ -406,20 +469,35 @@ void SFE_UBLOX_GPS::processUBXpacket(ubxPacket *msg)
406
469
}
407
470
}
408
471
409
- // Given a packet and payload, send everything including CRC bytes
410
- // Poll for a response, returning true if command was ack'd, false if we time out waiting for response
411
- // Setting timeout to 0 will skip checking for response - handy if you need to scan a raw response (like checking the PROTVER)
472
+ // Given a packet and payload, send everything including CRC bytes via I2C port
412
473
boolean SFE_UBLOX_GPS::sendCommand (ubxPacket outgoingUBX, uint16_t maxWait)
413
474
{
414
- commandAck = false ; // We're about to send a command. Begin waiting for ack.
415
-
416
- calcChecksum (&outgoingUBX); // Sets checksum A and B bytes of the packet
475
+ commandAck = false ; // We're about to send a command. Begin waiting for ack.
476
+ calcChecksum (&outgoingUBX); // Sets checksum A and B bytes of the packet
417
477
418
478
#ifdef DEBUG
419
- debug.print (" Sending: " );
420
- printPacket (&outgoingUBX);
479
+ debug.print (" Sending: " );
480
+ printPacket (&outgoingUBX);
421
481
#endif
422
482
483
+ if (commType == COMM_TYPE_I2C)
484
+ {
485
+ if (!sendI2cCommand (outgoingUBX, maxWait)) return false ;
486
+ } else if (commType == COMM_TYPE_SERIAL)
487
+ {
488
+ sendSerialCommand (outgoingUBX);
489
+ }
490
+
491
+ if (maxWait > 0 )
492
+ {
493
+ // Give waitForResponse the cls/id to check for
494
+ return waitForResponse (outgoingUBX.cls , outgoingUBX.id , maxWait); // Wait for Ack response
495
+ }
496
+ return true ;
497
+ }
498
+
499
+ boolean SFE_UBLOX_GPS::sendI2cCommand (ubxPacket outgoingUBX, uint16_t maxWait)
500
+ {
423
501
// Point at 0xFF data register
424
502
_i2cPort->beginTransmission ((uint8_t )_gpsI2Caddress); // There is no register to write to, we just begin writing data bytes
425
503
_i2cPort->write (0xFF );
@@ -468,27 +546,54 @@ boolean SFE_UBLOX_GPS::sendCommand(ubxPacket outgoingUBX, uint16_t maxWait)
468
546
if (bytesToSend == 1 ) _i2cPort->write (outgoingUBX.payload , 1 );
469
547
_i2cPort->write (outgoingUBX.checksumA );
470
548
_i2cPort->write (outgoingUBX.checksumB );
471
-
549
+
472
550
// All done transmitting bytes. Release bus.
473
551
if (_i2cPort->endTransmission () != 0 )
474
552
return (false ); // Sensor did not ACK
475
-
476
- if (maxWait > 0 )
477
- {
478
- // Give waitForResponse the cls/id to check for
479
- if (waitForResponse (outgoingUBX.cls , outgoingUBX.id , maxWait) == false ) // Wait for Ack response
480
- return (false );
481
- }
482
553
return (true );
483
554
}
484
555
556
+ // Given a packet and payload, send everything including CRC bytesA via Serial port
557
+ void SFE_UBLOX_GPS::sendSerialCommand (ubxPacket outgoingUBX)
558
+ {
559
+ // Write header bytes
560
+ _serialPort->write (UBX_SYNCH_1); // μ - oh ublox, you're funny. I will call you micro-blox from now on.
561
+ _serialPort->write (UBX_SYNCH_2); // b
562
+ _serialPort->write (outgoingUBX.cls );
563
+ _serialPort->write (outgoingUBX.id );
564
+ _serialPort->write (outgoingUBX.len & 0xFF ); // LSB
565
+ _serialPort->write (outgoingUBX.len >> 8 ); // MSB
566
+
567
+ // Write payload.
568
+ for (int i=0 ; i<outgoingUBX.len ; i++)
569
+ {
570
+ _serialPort->write (outgoingUBX.payload [i]);
571
+ }
572
+
573
+ // Write checksum
574
+ _serialPort->write (outgoingUBX.checksumA );
575
+ _serialPort->write (outgoingUBX.checksumB );
576
+ }
577
+
485
578
// Returns true if I2C device ack's
486
579
boolean SFE_UBLOX_GPS::isConnected ()
487
580
{
488
- _i2cPort->beginTransmission ((uint8_t )_gpsI2Caddress);
489
- if (_i2cPort->endTransmission () != 0 )
490
- return (false ); // Sensor did not ACK
491
- return (true );
581
+ if (commType == COMM_TYPE_I2C)
582
+ {
583
+ _i2cPort->beginTransmission ((uint8_t )_gpsI2Caddress);
584
+ return _i2cPort->endTransmission () == 0 ;
585
+ }
586
+ else if (commType == COMM_TYPE_SERIAL)
587
+ {
588
+ // Query navigation rate to see whether we get a meaningful response
589
+ packetCfg.cls = UBX_CLASS_CFG;
590
+ packetCfg.id = UBX_CFG_RATE;
591
+ packetCfg.len = 0 ;
592
+ packetCfg.startingSpot = 0 ;
593
+
594
+ return sendCommand (packetCfg);
595
+ }
596
+ return false ;
492
597
}
493
598
494
599
// Given a message, calc and store the two byte "8-Bit Fletcher" checksum over the entirety of the message
0 commit comments