Skip to content

Commit 5ef6439

Browse files
committed
Implement SoftwareSerial in gps component
1 parent 9750fdd commit 5ef6439

File tree

5 files changed

+115
-9
lines changed

5 files changed

+115
-9
lines changed

src/Wippersnapper_V2.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@
3030
*/
3131
#ifdef WS_DEBUG
3232
#define WS_DEBUG_PRINT(...) \
33-
{ WS_PRINTER.print(__VA_ARGS__); } /**< Print debug message to serial */
33+
{ \
34+
WS_PRINTER.print(__VA_ARGS__); \
35+
} /**< Print debug message to serial */
3436
#define WS_DEBUG_PRINTLN(...) \
3537
{ \
3638
WS_PRINTER.println(__VA_ARGS__); \
@@ -42,9 +44,11 @@
4244
} /**< Print debug message in hexadecimal */
4345
#else
4446
#define WS_DEBUG_PRINT(...) \
45-
{} /**< Debug print */
47+
{ \
48+
} /**< Debug print */
4649
#define WS_DEBUG_PRINTLN(...) \
47-
{} /**< Debug println */
50+
{ \
51+
} /**< Debug println */
4852
#endif
4953

5054
/*!

src/components/gps/controller.cpp

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ bool GPSController::AddGPS(TwoWire *wire, uint32_t i2c_addr,
7272
}
7373

7474
/*!
75-
* @brief Adds a GPS hardware instance to the controller.
75+
* @brief Adds a GPS hardware serial instance to the controller.
7676
* @param serial Pointer to the HardwareSerial instance for GPS communication.
7777
* @param gps_config Pointer to the GPS configuration message.
7878
* @return True if the GPS was added successfully, false otherwise.
@@ -107,6 +107,44 @@ bool GPSController::AddGPS(HardwareSerial *serial, uint32_t baudrate,
107107
return true;
108108
}
109109

110+
#ifdef HAS_SW_SERIAL
111+
/*!
112+
* @brief Adds a GPS software serial instance to the controller.
113+
* @param serial Pointer to the SoftwareSerial instance for GPS communication.
114+
* @param gps_config Pointer to the GPS configuration message.
115+
* @return True if the GPS was added successfully, false otherwise.
116+
*/
117+
bool GPSController::AddGPS(SoftwareSerial *serial_sw, uint32_t baudrate,
118+
wippersnapper_gps_GPSConfig *gps_config) {
119+
GPSHardware *gps_hw = new GPSHardware();
120+
121+
if (!gps_hw->SetInterface(serial_sw, baudrate)) {
122+
WS_DEBUG_PRINTLN("[gps] ERROR: Failed to set GPS UART interface!");
123+
delete gps_hw;
124+
return false;
125+
}
126+
127+
if (!gps_hw->begin()) {
128+
WS_DEBUG_PRINTLN("[gps] ERROR: Failed to initialize GPS hardware!");
129+
delete gps_hw;
130+
return false;
131+
}
132+
// Required - let the GPS spit out its initial data
133+
delay(1000);
134+
135+
if (!gps_hw->Handle_GPSConfig(gps_config)) {
136+
WS_DEBUG_PRINTLN("[gps] ERROR: Failed to configure GPS!");
137+
delete gps_hw;
138+
return false;
139+
}
140+
141+
_gps_drivers.push_back(gps_hw);
142+
WS_DEBUG_PRINTLN("[gps] GPS hardware added successfully!");
143+
has_gps = true;
144+
return true;
145+
}
146+
#endif // HAS_SW_SERIAL
147+
110148
/*!
111149
* @brief Gets the current GPS datetime.
112150
* @return The current GPS datetime.

src/components/gps/controller.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ class GPSController {
3333
~GPSController();
3434
bool AddGPS(HardwareSerial *serial, uint32_t baudrate,
3535
wippersnapper_gps_GPSConfig *gps_config);
36+
#ifdef HAS_SW_SERIAL
37+
bool AddGPS(SoftwareSerial *serial, uint32_t baudrate,
38+
wippersnapper_gps_GPSConfig *gps_config);
39+
#endif // HAS_SW_SERIAL
3640
bool AddGPS(TwoWire *wire, uint32_t i2c_addr,
3741
wippersnapper_gps_GPSConfig *gps_config);
3842
void update();

src/components/gps/hardware.cpp

Lines changed: 59 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,20 @@ bool GPSHardware::Handle_GPSConfig(wippersnapper_gps_GPSConfig *gps_config) {
8080
}
8181
WS_DEBUG_PRINT("[gps] Expected response: ");
8282
WS_DEBUG_PRINTLN(msg_resp);
83-
if (_iface_type == GPS_IFACE_UART_HW) {
84-
// Flush the RX/TX buffers before sending
83+
if (_iface_type == GPS_IFACE_UART_HW ||
84+
_iface_type == GPS_IFACE_UART_SW) {
85+
// Flush the RX/TX buffers before sending
86+
#ifdef HAS_SW_SERIAL
87+
_sw_serial->flush();
88+
while (_sw_serial->available() > 0) {
89+
_sw_serial->read();
90+
}
91+
#else
8592
_hw_serial->flush();
8693
while (_hw_serial->available() > 0) {
8794
_hw_serial->read();
8895
}
96+
#endif // HAS_SW_SERIAL
8997
} else if (_iface_type == GPS_IFACE_I2C) {
9098
WS_DEBUG_PRINT("[gps] Flushing I2C buffers...");
9199
I2cReadDiscard();
@@ -128,6 +136,24 @@ bool GPSHardware::SetInterface(HardwareSerial *serial, uint32_t baudrate) {
128136
return true;
129137
}
130138

139+
#ifdef HAS_SW_SERIAL
140+
/*!
141+
* @brief Sets a UART software serial interface for the GPS controller.
142+
* @param serial
143+
* Pointer to a SoftwareSerial instance.
144+
* @returns True if the interface was set successfully, False otherwise.
145+
*/
146+
bool GPSHardware::SetInterface(SoftwareSerial *serial, uint32_t baudrate) {
147+
if (serial == nullptr)
148+
return false;
149+
// Configure the hardware serial interface
150+
_sw_serial = serial;
151+
_iface_type = GPS_IFACE_UART_SW;
152+
_baudrate = baudrate;
153+
return true;
154+
}
155+
#endif // HAS_SW_SERIAL
156+
131157
/*!
132158
* @brief Sets a TwoWire (I2C) interface for the GPS controller.
133159
* @param wire
@@ -259,33 +285,57 @@ bool GPSHardware::DetectMtkUart() {
259285
return false;
260286
}
261287

262-
// Clear the tx and rx buffers before sending the command
288+
// Clear the tx and rx buffers before sending the command
289+
#ifdef HAS_SW_SERIAL
290+
_sw_serial->flush();
291+
while (_sw_serial->available() > 0) {
292+
_sw_serial->read();
293+
}
294+
#else
263295
_hw_serial->flush();
264296
while (_hw_serial->available() > 0) {
265297
_hw_serial->read();
266298
}
299+
#endif
267300

268301
// Query MediaTek firmware version
269302
uint16_t timeout = MTK_QUERY_FW_TIMEOUT;
303+
304+
#ifdef HAS_SW_SERIAL
305+
while (_sw_serial->available() < MAX_NEMA_SENTENCE_LEN && timeout--) {
306+
delay(1);
307+
}
308+
#else
270309
while (_hw_serial->available() < MAX_NEMA_SENTENCE_LEN && timeout--) {
271310
delay(1);
272311
}
312+
#endif // HAS_SW_SERIAL
313+
273314
if (timeout == 0)
274315
return false;
275316

276317
// We found a response, let's verify that it's the expected PMTK_DK_RELEASE
277318
// command by reading out the NMEA sentence string into a buffer
278319
size_t buf_len = MAX_NEMA_SENTENCE_LEN * 4; // +3 for \r\n and null terminator
279320
char buffer[buf_len];
280-
size_t available = _hw_serial->available();
321+
size_t available;
322+
#ifdef HAS_SW_SERIAL
323+
available = _sw_serial->available();
324+
#else
325+
available = _hw_serial->available();
326+
#endif // HAS_SW_SERIAL
281327
size_t bytes_to_read = min(available, buf_len - 1);
282328
// Print the two out
283329
WS_DEBUG_PRINT("[gps] Reading MediaTek GPS response: ");
284330
WS_DEBUG_PRINT(available);
285331
WS_DEBUG_PRINT(" bytes, reading ");
286332
WS_DEBUG_PRINTLN(bytes_to_read);
287333
for (size_t i = 0; i < bytes_to_read; i++) {
334+
#ifdef HAS_SW_SERIAL
335+
buffer[i] = _sw_serial->read();
336+
#else
288337
buffer[i] = _hw_serial->read();
338+
#endif // HAS_SW_SERIAL
289339
}
290340
buffer[bytes_to_read] = '\0';
291341
WS_DEBUG_PRINT("[gps] MediaTek GPS response: ");
@@ -295,8 +345,12 @@ bool GPSHardware::DetectMtkUart() {
295345
return false;
296346
}
297347

298-
// Attempt to use Adafruit_GPS
348+
// Attempt to use Adafruit_GPS
349+
#ifdef HAS_SW_SERIAL
350+
_ada_gps = new Adafruit_GPS(_sw_serial);
351+
#else
299352
_ada_gps = new Adafruit_GPS(_hw_serial);
353+
#endif // HAS_SW_SERIAL
300354
if (!_ada_gps->begin(_baudrate)) {
301355
WS_DEBUG_PRINTLN("[gps] ERROR: Failed to initialize Mediatek!");
302356
return false;

src/components/gps/hardware.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ class GPSHardware {
7070
~GPSHardware();
7171
bool begin();
7272
bool SetInterface(HardwareSerial *serial, uint32_t baudrate);
73+
#ifdef HAS_SW_SERIAL
74+
bool SetInterface(SoftwareSerial *serial, uint32_t baudrate);
75+
#endif // HAS_SW_SERIAL
7376
bool SetInterface(TwoWire *wire);
7477
void SetPollPeriod(ulong poll_period);
7578
void SetPollPeriodPrv(ulong poll_period_prv);
@@ -127,6 +130,9 @@ class GPSHardware {
127130
GpsInterfaceType _iface_type; ///< Type of interface used by GPS
128131
GpsDriverType _driver_type; ///< Type of GPS driver used by GPS
129132
HardwareSerial *_hw_serial = nullptr; ///< Optional HardwareSerial instance
133+
#ifdef HAS_SW_SERIAL
134+
SoftwareSerial *_sw_serial = nullptr; ///< Optional SoftwareSerial instance
135+
#endif // HAS_SW_SERIAL
130136
TwoWire *_wire = nullptr; ///< Optional TwoWire instance
131137
Adafruit_GPS *_ada_gps = nullptr; ///< Optional Adafruit GPS instance
132138
Adafruit_UBloxDDC *_ubx_gps_ddc =

0 commit comments

Comments
 (0)