-
Notifications
You must be signed in to change notification settings - Fork 128
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
use QSerialPort for garmin serial communication. #1279
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really like this.
I'm on the road and can't help test this, but agree that this probably needs some special attention.
|
||
if (!GPS_Serial_Open((gpsdevh*) psd,port)) { | ||
GPS_Error("Cannot open serial port '%s'", port); | ||
auto* h = reinterpret_cast<serial_data_handle*>(dh); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All this funky casting of things into. a void* was necessary and hip when we were C. I know it's another shelf of cans of worms, but I wonder if we should just make serial_data_handle a "real" data structure and quit this funky casting.
What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The casting almost entirely goes away in the next step, when GpsDevice becomes a base class with derived classes GpsSerialDevice and GpsUsbDevice. That obviously touches the usb communication, another thing I can't test, but if you really like what you have seen so far I think you will like that even more.
xfree(dh); | ||
return 1; | ||
/* Process IO */ | ||
(void) GPS_Serial_Chars_Ready(dh); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this now be [[maybe_unused]]?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No.
warning: attributes at the beginning of statement are ignored [-Wattributes]
239 | [[maybe_unused]] GPS_Serial_Chars_Ready(dh);
|
||
// Sleep for a small amount of time, about 100 milliseconds, | ||
// to make sure the packet was successfully transmitted to the GPS unit. | ||
QThread::usleep(100000); | ||
QThread::usleep(100000); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems like Device_Flush and/or Wait should do something more appropriate for us. Can one of those maybe do a https://doc.qt.io/qt-6/qserialport.html#flush for us to do a TCSADRAIN or something and eliminate this?
I get that you only changed whitespace here...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The original code looks wrong to me!
GPS_Device_Flush on unix calls tcflush(), which I think I correclty translated to QSerialPort::clear().
But tcflush discards data, it doesn't send it on its way.
tcflush() discards data written to the object referred to by fd but not transmitted, or data received but not read, depending on the value of queue_selector:
What GPS_18x_Tech_Specs.pdf says is to wait a small amount of time to make sure the previous packet (the ACK of IOP_BAUD_ACPT_DATA) is complete. So it sounds to me like we wanted to call tcdrain() instead of tcflush(), which would translate to QSerialPort::flush(). QSerialPort::flush() may not be necessary after QSerialPort::waitForBytesWritten.
I note that GPS_18x_Tech_Specs were updated 1/2024!
I cant test this as the GPS12 doesn't support baud rate changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ISTR that Garmin protocol is always 9600, Period. I'm not even sure why this is exposed.
The original code being wrong wouldn't shock me. I had to fix a LOT of stuff in Jeeps serial, maybe even before I checked it in the first time. My own fixes may not have been water-tight. I remember having concerns about the way data was shoved around synchronously in some places and more loosely in others. When I simulated really losing data and forcing protocol retries, it largely came unglued
return gps_errno; | ||
} | ||
|
||
if (global_opts.debug_level >= 1) fprintf(stderr, "Serial port speed set to %d\n", br); | ||
if (global_opts.debug_level >= 1) { | ||
fprintf(stderr, "Serial port speed set to %d\n", br); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we push this into a qDebug() or a Warning() or one of our other existing methods?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had difficulty preserving order when I mixed the qDebug messages with traditional fprintf messages jeeps used in GPS_Diag. For consistency perhaps this always should have used GPS_Error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe, but it's not really an error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When I'm back after GeoWoodstock,. I'll retest with at least two USB protocol and two USB serial (perhaps using something like a 60csx that provides both)
I'll also look ask my geocaching friends what's in their hand-me-down drawer and buy/ship you some representative hardware if you like.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a GPS12 that does 9600 serial only. I have no way to test baud rate changes. Baud rate changes were supported by some variants of the GPS 18. GPS 15xH/15xL had user-selectable baud: 4800, 9600, 19200, 38400. The return code from GPS_Serial_Set_Baud_Rate is also problematic, e.g. success and a tcsetattr error both return 0.
I don't have a usb device, so anything that could allow me to test gpsusb* would be useful as well. That would enable the next step - make GpsDevice an abstract base class - which gets rid of a bunch of casting and gpsdeviceops.
I have an 18. It is a puck <https://www.garmin.com/en-US/p/223> product
with no screen. It's a PVT/NMEA device only. You can't transfer waypoints,
routes, or tracks to/from it. All it knows how to do is shout out the
current location every N second. I can't remember any evidence that the
device had any storage at all of the types we care about. ISTR ensuring
that we didn't crash when talking to lt was abot all we could do with that
one beyond NMEA and PVT.
The 15 looks to be a little module
<https://www.garmin.com/en-US/p/51048/pn/010-00240-31?srsltid=AfmBOoqSD0r2WAwDSuXi5zho7N9fbdKbNRHNdpvjjHtT-C0FnQN6aqJdq2Y>
that's again just not applicable in our world, isn't it? (So you could
imagine it being an 18 without the serial bridge and case.)
I'm not sure they're applicable to us, are they?
I glanced at eBay and they're priced a little crazy. They should be priced
like salvage, not collectors items. :-) I'm pretty sure I can find some in
old junk drawers once I can ask the right people.kk
I've thought in the past about doing crazy things like writing a Garmin
protso emulation test jig something like the STM32 or ESP32
<https://www.aliexpress.us/item/2251832814839254.html?>. A little dash of
ESP-IDF, sweeten with some protocol implementation
<https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/api-reference/peripherals/usb_device.html>
and
then I'd have a customizable fake Garmin for packet capture and testing.
But this is a fairly terrible idea because we've not needed to do any
non-trivial Garmin USB dev in fifteen years and I don't really need another
project. The idea just keeps coming up in my mind because it's something
that came up in the past when I DID want to automate such things.
I'll try to find one or more for you. It'll just take a bit since the group
I'm thinking of is about to be on the road.
RJL
…On Fri, May 17, 2024 at 6:18 PM tsteven4 ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In jeeps/gpsserial.cc
<#1279 (comment)>:
> return gps_errno;
}
- if (global_opts.debug_level >= 1) fprintf(stderr, "Serial port speed set to %d\n", br);
+ if (global_opts.debug_level >= 1) {
+ fprintf(stderr, "Serial port speed set to %d\n", br);
I have a GPS12 that does 9600 serial only. I have no way to test baud rate
changes. Baud rate changes were supported by some variants of the GPS 18.
GPS 15xH/15xL had user-selectable baud: 4800, 9600, 19200, 38400. The
return code from GPS_Serial_Set_Baud_Rate is also problematic, e.g. success
and a tcsetattr error both return 0.
I don't have a usb device, so anything that could allow me to test gpsusb*
would be useful as well. That would enable the next step - make GpsDevice
an abstract base class - which gets rid of a bunch of casting and
gpsdeviceops.
—
Reply to this email directly, view it on GitHub
<#1279 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ACCSD3YFMNRMQNBZA4NOO2LZC2F5JAVCNFSM6AAAAABHYRSL2GVHI2DSMVQWIX3LMV43YUDVNRWFEZLROVSXG5CSMV3GSZLXHMZDANRUGQ4DKMBRGM>
.
You are receiving this because you commented.Message ID:
***@***.***>
|
This moves OS specific code out of gpsbabel (taking advantage of OS specific code in QSerialPort). I have tested this with a GPS12 but I am unable to test the baudrate option with that device.
I have conversion of gpsdeviceh to a base class GpsDevice, with subclasses GpsSerialDevice and GpsUsbDevice. I am unable to test GpsUsbDevice at all.
Can we come up with a testing plan? Test in the GPSBabel lab? Relocate some devices to the GPSBabel west lab?