ref: 891df3a84e4ca05c9b30c81b160b23f1408a96a1
parent: 393a3e1397be03d7e34bcc65829dcebec18f2146
author: Maido Käära <maido@producement.com>
date: Sat Mar 23 10:06:20 EDT 2024
Device selection in libusb Achieve parity with libserialport implementation.
--- a/src/main.c
+++ b/src/main.c
@@ -29,12 +29,12 @@
int main(int argc, char *argv[]) {- if(argc == 2 && strcmp(argv[1], "--list") == 0) {+ if(argc == 2 && SDL_strcmp(argv[1], "--list") == 0) {return list_devices();
}
char *preferred_device = NULL;
- if (argc == 3 && strcmp(argv[1], "--dev") == 0) {+ if (argc == 3 && SDL_strcmp(argv[1], "--dev") == 0) {preferred_device = argv[2];
SDL_Log("Using preferred device %s.\n", preferred_device);}
@@ -99,7 +99,7 @@
// try to init serial port
int port_inited = init_serial(1, preferred_device);
// if port init was successful, try to enable and reset display
- if (port_inited == 1 && enable_and_reset_display(0) == 1) {+ if (port_inited == 1 && enable_and_reset_display() == 1) {// if audio routing is enabled, try to initialize audio devices
if (conf.audio_enabled == 1) {audio_init(conf.audio_buffer_size, conf.audio_device_name);
--- a/src/serial.c
+++ b/src/serial.c
@@ -48,7 +48,7 @@
struct sp_port *port = port_list[i];
if (detect_m8_serial_device(port)) {- SDL_Log("Found M8 device: %s", sp_get_port_name(port));+ printf("Found M8 device: %s", sp_get_port_name(port));}
}
--- a/src/usb.c
+++ b/src/usb.c
@@ -18,11 +18,42 @@
#define ACM_CTRL_DTR 0x01
#define ACM_CTRL_RTS 0x02
+#define M8_VID 0x16c0
+#define M8_PID 0x048a
+
libusb_context *ctx = NULL;
libusb_device_handle *devh = NULL;
static int do_exit = 0;
+int list_devices() {+ int r;
+ r = libusb_init(&ctx);
+ if (r < 0) {+ SDL_Log("libusb_init failed: %s", libusb_error_name(r));+ return 0;
+ }
+
+ libusb_device **device_list = NULL;
+ int count = libusb_get_device_list(ctx, &device_list);
+ for (size_t idx = 0; idx < count; ++idx) {+ libusb_device *device = device_list[idx];
+ struct libusb_device_descriptor desc;
+ int rc = libusb_get_device_descriptor(device, &desc);
+ if (rc < 0) {+ SDL_Log("Error");+ libusb_free_device_list(device_list, 1);
+ return rc;
+ }
+
+ if (desc.idVendor == M8_VID && desc.idProduct == M8_PID) {+ printf("Found M8 device: %d:%d\n", libusb_get_port_number(device), libusb_get_bus_number(device));+ }
+ }
+ libusb_free_device_list(device_list, 1);
+ return 0;
+ }
+
int usb_loop(void *data) {SDL_SetThreadPriority(SDL_THREAD_PRIORITY_TIME_CRITICAL);
while (!do_exit) {@@ -170,7 +201,7 @@
return init_interface();
}
-int init_serial(int verbose) {+int init_serial(int verbose, char *preferred_device) { if (devh != NULL) {return 1;
@@ -182,7 +213,44 @@
SDL_Log("libusb_init failed: %s", libusb_error_name(r));return 0;
}
- devh = libusb_open_device_with_vid_pid(ctx, 0x16c0, 0x048a);
+ if(preferred_device == NULL) {+ devh = libusb_open_device_with_vid_pid(ctx, M8_VID, M8_PID);
+ } else {+ char *port;
+ char *saveptr = NULL;
+ char *bus;
+ port = SDL_strtokr(preferred_device, ":", &saveptr);
+ bus = SDL_strtokr(NULL, ":", &saveptr);
+ libusb_device **device_list = NULL;
+ int count = libusb_get_device_list(ctx, &device_list);
+ for (size_t idx = 0; idx < count; ++idx) {+ libusb_device *device = device_list[idx];
+ struct libusb_device_descriptor desc;
+ r = libusb_get_device_descriptor(device, &desc);
+ if (r < 0) {+ SDL_Log("libusb_get_device_descriptor failed: %s", libusb_error_name(r));+ libusb_free_device_list(device_list, 1);
+ return 0;
+ }
+
+ if (desc.idVendor == M8_VID && desc.idProduct == M8_PID) {+ SDL_Log("Searching for port %s and bus %s", port, bus);+ if (libusb_get_port_number(device) == SDL_atoi(port) && libusb_get_bus_number(device) == SDL_atoi(bus)) {+ SDL_Log("Preferred device found, connecting");+ r = libusb_open(device, &devh);
+ if (r < 0) {+ SDL_Log("libusb_open failed: %s", libusb_error_name(r));+ return 0;
+ }
+ }
+ }
+ }
+ libusb_free_device_list(device_list, 1);
+ if(devh == NULL) {+ SDL_Log("Preferred device %s not found, using first available", preferred_device);+ devh = libusb_open_device_with_vid_pid(ctx, M8_VID, M8_PID);
+ }
+ }
if (devh == NULL) { SDL_Log("libusb_open_device_with_vid_pid returned invalid handle");return 0;
--
⑨