Skip to content

Commit 320fa1e

Browse files
committed
GPS - I2C integration, Handle_GPSConfig not working yet
1 parent 642733e commit 320fa1e

File tree

7 files changed

+150
-57
lines changed

7 files changed

+150
-57
lines changed

src/components/gps/controller.cpp

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,41 @@ GPSController::~GPSController() {
3636
}
3737
}
3838

39+
/*!
40+
* @brief Adds an I2C GPS hardware instance to the controller.
41+
* @param wire Pointer to the TwoWire instance for I2C communication.
42+
* @param i2c_addr I2C address of the GPS device.
43+
* @param gps_config Pointer to the GPS configuration message.
44+
* @return True if the GPS was added successfully, false otherwise.
45+
*/
46+
bool GPSController::AddGPS(TwoWire *wire, uint32_t i2c_addr,
47+
wippersnapper_gps_GPSConfig *gps_config) {
48+
GPSHardware *gps_hw = new GPSHardware();
49+
50+
if (!gps_hw->SetInterface(wire)) {
51+
WS_DEBUG_PRINTLN("[gps] ERROR: Failed to set module interface!");
52+
delete gps_hw;
53+
return false;
54+
}
55+
56+
gps_hw->SetI2CAddress(i2c_addr);
57+
if (!gps_hw->begin()) {
58+
WS_DEBUG_PRINTLN("[gps] ERROR: Failed to initialize module!");
59+
delete gps_hw;
60+
return false;
61+
}
62+
63+
if (!gps_hw->Handle_GPSConfig(gps_config)) {
64+
WS_DEBUG_PRINTLN("[gps] ERROR: Configuration failed!");
65+
delete gps_hw;
66+
return false;
67+
}
68+
69+
_gps_drivers.push_back(gps_hw);
70+
WS_DEBUG_PRINTLN("[gps] GPS hardware added successfully!");
71+
return true;
72+
}
73+
3974
/*!
4075
* @brief Adds a GPS hardware instance to the controller.
4176
* @param serial Pointer to the HardwareSerial instance for GPS communication.
@@ -47,7 +82,7 @@ bool GPSController::AddGPS(HardwareSerial *serial,
4782
GPSHardware *gps_hw = new GPSHardware();
4883

4984
if (!gps_hw->SetInterface(serial)) {
50-
WS_DEBUG_PRINTLN("[gps] ERROR: Failed to set GPS interface!");
85+
WS_DEBUG_PRINTLN("[gps] ERROR: Failed to set GPS UART interface!");
5186
delete gps_hw;
5287
return false;
5388
}

src/components/gps/controller.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ class GPSController {
4242
GPSController();
4343
~GPSController();
4444
bool AddGPS(HardwareSerial *serial, wippersnapper_gps_GPSConfig *gps_config);
45+
bool AddGPS(TwoWire *wire, uint32_t i2c_addr,
46+
wippersnapper_gps_GPSConfig *gps_config);
4547
void update();
4648

4749
private:

src/components/gps/hardware.cpp

Lines changed: 65 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
GPSHardware::GPSHardware() {
2121
_iface_type = GPS_IFACE_NONE;
2222
_driver_type = GPS_DRV_NONE;
23+
_nmea_baud_rate = DEFAULT_MTK_NMEA_BAUD_RATE;
24+
_nmea_update_rate = DEFAULT_MTK_NMEA_UPDATE_RATE;
2325
}
2426

2527
/*!
@@ -96,22 +98,36 @@ bool GPSHardware::Handle_GPSConfig(wippersnapper_gps_GPSConfig *gps_config) {
9698
bool GPSHardware::SetInterface(HardwareSerial *serial) {
9799
if (serial == nullptr)
98100
return false;
99-
// Set the hardware serial interface
101+
// Configure the hardware serial interface
100102
_hw_serial = serial;
101103
_iface_type = GPS_IFACE_UART_HW;
102104
return true;
103105
}
104106

107+
/*!
108+
* @brief Sets a TwoWire (I2C) interface for the GPS controller.
109+
* @param wire
110+
* Points to a TwoWire instance.
111+
* @returns True if the interface was set successfully, False otherwise.
112+
*/
113+
bool GPSHardware::SetInterface(TwoWire *wire) {
114+
if (wire == nullptr)
115+
return false;
116+
// Configure the I2C interface
117+
_wire = wire;
118+
_iface_type = GPS_IFACE_I2C;
119+
return true;
120+
}
121+
105122
/*!
106123
* @brief Attempts to initialize the GPS device based on the configured
107124
* interface type.
108125
* @returns True if the GPS device was initialized successfully, False
109126
* otherwise.
110127
*/
111128
bool GPSHardware::begin() {
112-
// Validate if the interface type is set
113129
if (_iface_type == GPS_IFACE_NONE) {
114-
WS_DEBUG_PRINTLN("[gps] ERROR: No interface type configured!");
130+
WS_DEBUG_PRINTLN("[gps] ERROR: No interface configured for GPS!");
115131
return false;
116132
}
117133

@@ -120,9 +136,8 @@ bool GPSHardware::begin() {
120136
WS_DEBUG_PRINTLN("[gps] ERROR: Failed to query GPS module type!");
121137
return false;
122138
}
139+
WS_DEBUG_PRINTLN("[gps] Module detected, ready for commands!");
123140

124-
WS_DEBUG_PRINTLN(
125-
"[gps] GPS module type detected successfully and ready for commands!");
126141
return true;
127142
}
128143

@@ -132,32 +147,48 @@ bool GPSHardware::begin() {
132147
* @returns True if the driver type was detected successfully, False otherwise.
133148
*/
134149
bool GPSHardware::QueryModuleType() {
135-
// Validate if the interface is set
136-
if (_iface_type == GPS_IFACE_NONE) {
137-
WS_DEBUG_PRINTLN("[gps] ERROR: No interface configured for GPS!");
138-
return false;
139-
}
140150
WS_DEBUG_PRINTLN("[gps] Attempting to detect GPS module type...");
141151

142-
// Try to detect MediaTek GPS module
143-
if (DetectMediatek()) {
144-
WS_DEBUG_PRINTLN("[gps] Using MediaTek GPS driver!");
145-
return true;
146-
}
147-
148-
WS_DEBUG_PRINTLN("[gps] Failed to detect MTK GPS, attempting to detect "
149-
"u-blox GPS module...");
150-
// TODO: Implement u-blox detection here
151-
// if (DetectUblox()) {
152-
// return true;
153-
// }
152+
if (_iface_type == GPS_IFACE_UART_HW) {
153+
// Try to detect MediaTek GPS module
154+
if (DetectMediatek()) {
155+
WS_DEBUG_PRINTLN("[gps] Using MediaTek GPS driver!");
156+
return true;
157+
}
154158

155-
WS_DEBUG_PRINTLN("[gps] ERROR: Failed to detect GPS driver type, attempting "
156-
"to use generic driver!");
157-
// TODO: Implement generic NMEA GPS driver detection
159+
WS_DEBUG_PRINTLN("[gps] Failed to detect MTK GPS, attempting to detect "
160+
"u-blox GPS module...");
161+
// TODO: Implement u-blox detection here
162+
// if (DetectUblox()) {
163+
// return true;
164+
// }
165+
166+
WS_DEBUG_PRINTLN(
167+
"[gps] ERROR: Failed to detect GPS driver type, attempting "
168+
"to use generic driver!");
169+
// TODO: Implement generic NMEA GPS driver detection
170+
171+
// No responses from the GPS module over the defined iface, so we bail out
172+
WS_DEBUG_PRINTLN("[gps] ERROR: No GPS driver type detected!");
173+
} else if (_iface_type == GPS_IFACE_I2C) {
174+
if (_addr == PA1010D_I2C_ADDRESS) {
175+
WS_DEBUG_PRINT("[gps] Attempting to use PA1010D driver...");
176+
// Attempt to use Adafruit_GPS I2c interface
177+
_ada_gps = new Adafruit_GPS(_hw_serial);
178+
if (!_ada_gps->begin(_addr)) {
179+
WS_DEBUG_PRINTLN("[gps] ERROR: Failed to initialize Mediatek!");
180+
return false;
181+
}
182+
WS_DEBUG_PRINTLN("ok!");
183+
_driver_type = GPS_DRV_MTK;
184+
return true;
185+
} else {
186+
WS_DEBUG_PRINTLN(
187+
"[gps] ERROR: Only PA1010D i2c module is supported at this time!");
188+
return false;
189+
}
190+
}
158191

159-
// No responses from the GPS module over the defined iface, so we bail out
160-
WS_DEBUG_PRINTLN("[gps] ERROR: No GPS driver type detected!");
161192
return false;
162193
}
163194

@@ -212,17 +243,12 @@ bool GPSHardware::DetectMediatek() {
212243
}
213244

214245
// Attempt to use Adafruit_GPS
215-
if (_ada_gps != nullptr) {
216-
delete _ada_gps; // Clean up previous instance if it exists
217-
}
218246
_ada_gps = new Adafruit_GPS(_hw_serial);
219247
if (!_ada_gps->begin(_hw_serial->baudRate())) {
220248
WS_DEBUG_PRINTLN("[gps] ERROR: Failed to initialize Mediatek!");
221249
return false;
222250
}
223251
_driver_type = GPS_DRV_MTK;
224-
_nmea_baud_rate = DEFAULT_MTK_NMEA_BAUD_RATE;
225-
_nmea_update_rate = DEFAULT_MTK_NMEA_UPDATE_RATE;
226252
return true;
227253
}
228254

@@ -313,6 +339,13 @@ void GPSHardware::SetNmeaBaudRate(int nmea_baud_rate) {
313339
*/
314340
int GPSHardware::GetNmeaBaudRate() { return _nmea_baud_rate; }
315341

342+
/*!
343+
* @brief Sets the I2C address for a GPS.
344+
* @param i2c_address
345+
* The I2C address to set for the GPS device.
346+
*/
347+
void GPSHardware::SetI2CAddress(uint32_t i2c_address) { _addr = i2c_address; }
348+
316349
/*!
317350
* @brief Sets the last time the GPS hardware was polled.
318351
* @param kat_prv

src/components/gps/hardware.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#define DEFAULT_MTK_NMEA_UPDATE_RATE 1 ///< Default NMEA update rate in Hz
2727
#define DEFAULT_MTK_NMEA_BAUD_RATE 9600 ///< Default NMEA baud rate in bits per
2828
#define MAX_NEMA_SENTENCE_LEN 82 ///< Maximum length of a NMEA sentence
29+
#define PA1010D_I2C_ADDRESS 0x10 ///< I2C address for PA1010D GPS module
2930

3031
class Wippersnapper_V2; ///< Forward declaration
3132
class UARTHardware; ///< Forward declaration
@@ -56,6 +57,7 @@ class GPSHardware {
5657
~GPSHardware();
5758
bool begin();
5859
bool SetInterface(HardwareSerial *serial);
60+
bool SetInterface(TwoWire *wire);
5961
void SetPollPeriod(ulong poll_period);
6062
void SetPollPeriodPrv(ulong poll_period_prv);
6163
ulong GetPollPeriod();
@@ -66,7 +68,7 @@ class GPSHardware {
6668
int GetNmeaUpdateRate();
6769
void SetNmeaBaudRate(int nmea_baud_rate);
6870
int GetNmeaBaudRate();
69-
// TODO: Add SetInterface(I2C *_i2c_hardware) for I2C support here!
71+
void SetI2CAddress(uint32_t i2c_address);
7072
bool Handle_GPSConfig(wippersnapper_gps_GPSConfig *gps_config);
7173
Adafruit_GPS *GetAdaGps();
7274
GpsDriverType GetDriverType();
@@ -78,12 +80,12 @@ class GPSHardware {
7880
GpsInterfaceType _iface_type; ///< Type of interface used by GPS
7981
GpsDriverType _driver_type; ///< Type of GPS driver used
8082
HardwareSerial *_hw_serial = nullptr; ///< HardwareSerial instance for GPS;
83+
TwoWire *_wire = nullptr; ///< TwoWire instance for I2C GPS
8184
Adafruit_GPS *_ada_gps = nullptr; ///< Adafruit GPS instance
82-
ulong _period; ///< Polling period for GPS data (Specified by IO), in
83-
///< milliseconds
84-
ulong _period_prv; ///< Previous period for GPS data (Specified by IO), in
85-
///< milliseconds
86-
ulong _kat_prv; ///< Last time the GPS hardware was polled, in milliseconds
85+
uint32_t _addr; ///< I2C address for GPS device
86+
ulong _period; ///< Polling period for GPS data (Specified by IO), in ms
87+
ulong _period_prv; ///< Previous period for GPS data (Specified by IO), in ms
88+
ulong _kat_prv; ///< Last time the GPS hardware was polled, in ms
8789
int _nmea_update_rate; ///< NMEA update rate for GPS data, in Hz
8890
int _nmea_baud_rate; ///< NMEA baud rate for GPS data, in bits per second
8991
};

src/components/i2c/controller.cpp

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -881,7 +881,7 @@ bool I2cController::Handle_I2cDeviceAddOrReplace(pb_istream_t *stream) {
881881
bool is_output = _i2c_model->GetI2cDeviceAddOrReplaceMsg()->is_output;
882882

883883
// Is this a i2c GPS?
884-
bool is_gps = _i2c_model->GetI2cDeviceAddOrReplaceMsg()->has_gps_config;
884+
bool is_gps = _i2c_model->GetI2cDeviceAddOrReplaceMsg()->is_gps;
885885

886886
// TODO [Online]: Handle Replace messages by implementing the Remove handler
887887
// first...then proceed to adding a new device
@@ -954,14 +954,9 @@ bool I2cController::Handle_I2cDeviceAddOrReplace(pb_istream_t *stream) {
954954
bool did_init = false;
955955
drvBase *drv = nullptr;
956956
drvOutputBase *drv_out = nullptr;
957-
if (!is_output) {
958-
drv = CreateI2cSensorDrv(device_name, bus,
959-
device_descriptor.i2c_device_address,
960-
device_descriptor.i2c_mux_channel, device_status);
961-
if (drv != nullptr) {
962-
did_init = true;
963-
}
964-
} else {
957+
GPSController *drv_uart_gps = nullptr;
958+
959+
if (is_output) {
965960
WS_DEBUG_PRINT("[i2c] Creating an I2C output driver...");
966961
drv_out = CreateI2cOutputDrv(
967962
device_name, bus, device_descriptor.i2c_device_address,
@@ -970,10 +965,30 @@ bool I2cController::Handle_I2cDeviceAddOrReplace(pb_istream_t *stream) {
970965
did_init = true;
971966
}
972967
WS_DEBUG_PRINTLN("OK!");
968+
} else if (is_gps) {
969+
WS_DEBUG_PRINT("[i2c] Creating a GPS driver...");
970+
// TODO: You were here!
971+
// bool GPSController::AddGPS(TwoWire *wire, uint32_t i2c_addr, wippersnapper_gps_GPSConfig *gps_config) {
972+
if (!WsV2._gps_controller->AddGPS(bus, device_descriptor.i2c_device_address, &_i2c_model->GetI2cDeviceAddOrReplaceMsg()->gps_config)) {
973+
did_init = false;
974+
WS_DEBUG_PRINTLN("FAILURE!");
975+
} else {
976+
did_init = true;
977+
WS_DEBUG_PRINTLN("OK!");
978+
// TODO: We are doing an early-out here and should publish back to IO!
979+
return true;
980+
}
981+
} else {
982+
drv = CreateI2cSensorDrv(device_name, bus,
983+
device_descriptor.i2c_device_address,
984+
device_descriptor.i2c_mux_channel, device_status);
985+
if (drv != nullptr) {
986+
did_init = true;
987+
}
973988
}
974989

975990
if (!did_init) {
976-
WS_DEBUG_PRINTLN("[i2c] ERROR: I2C driver type not found or unsupported!");
991+
WS_DEBUG_PRINTLN("[i2c] ERROR: I2C driver failed to initialize!");
977992
if (WsV2._sdCardV2->isModeOffline()) {
978993
WsV2.haltErrorV2("[i2c] Driver failed to initialize!\n\tDid you set "
979994
"the correct value for i2cDeviceName?\n\tDid you set "

0 commit comments

Comments
 (0)