@@ -48,10 +48,70 @@ boolean SFE_UBLOX_GPS::begin(TwoWire &wirePort, uint8_t deviceAddress)
4848 // _i2cPort->begin();
4949
5050 _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+
5261 return (isConnected ());
5362}
5463
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+
55115// Changes the I2C address that the Ublox module responds to
56116// 0x42 is the default but can be changed with this command
57117boolean SFE_UBLOX_GPS::setI2CAddress (uint8_t deviceAddress, uint16_t maxWait)
@@ -89,6 +149,7 @@ boolean SFE_UBLOX_GPS::checkUblox()
89149 checkUbloxI2C ();
90150 else if (commType == COMM_TYPE_SERIAL)
91151 checkUbloxSerial ();
152+ return false ;
92153}
93154
94155// Polls I2C for data, passing any new bytes to process()
@@ -150,12 +211,14 @@ boolean SFE_UBLOX_GPS::checkUbloxI2C()
150211
151212} // end checkUbloxI2C()
152213
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()
155215boolean SFE_UBLOX_GPS::checkUbloxSerial ()
156216{
157- // Todo
158- return (true );
217+ while (_serialPort->available ())
218+ {
219+ process (_serialPort->read ());
220+ }
221+ return (true );
159222
160223} // end checkUbloxSerial()
161224
@@ -406,20 +469,35 @@ void SFE_UBLOX_GPS::processUBXpacket(ubxPacket *msg)
406469 }
407470}
408471
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
412473boolean SFE_UBLOX_GPS::sendCommand (ubxPacket outgoingUBX, uint16_t maxWait)
413474{
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
417477
418478#ifdef DEBUG
419- debug.print (" Sending: " );
420- printPacket (&outgoingUBX);
479+ debug.print (" Sending: " );
480+ printPacket (&outgoingUBX);
421481#endif
422482
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+ {
423501 // Point at 0xFF data register
424502 _i2cPort->beginTransmission ((uint8_t )_gpsI2Caddress); // There is no register to write to, we just begin writing data bytes
425503 _i2cPort->write (0xFF );
@@ -468,27 +546,54 @@ boolean SFE_UBLOX_GPS::sendCommand(ubxPacket outgoingUBX, uint16_t maxWait)
468546 if (bytesToSend == 1 ) _i2cPort->write (outgoingUBX.payload , 1 );
469547 _i2cPort->write (outgoingUBX.checksumA );
470548 _i2cPort->write (outgoingUBX.checksumB );
471-
549+
472550 // All done transmitting bytes. Release bus.
473551 if (_i2cPort->endTransmission () != 0 )
474552 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- }
482553 return (true );
483554}
484555
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+
485578// Returns true if I2C device ack's
486579boolean SFE_UBLOX_GPS::isConnected ()
487580{
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 ;
492597}
493598
494599// Given a message, calc and store the two byte "8-Bit Fletcher" checksum over the entirety of the message
0 commit comments