shithub: m8c

Download patch

ref: c4925e53b1724c5cb1857f89fd55600da28e5847
parent: 393a3e1397be03d7e34bcc65829dcebec18f2146
parent: 35f6ae756cfcf1e0fc72f2c995ca632a84d8132b
author: Jonne Kokkonen <jonne.kokkonen@gmail.com>
date: Thu Apr 18 03:41:59 EDT 2024

Merge pull request #141 from v3rm0n/libusb-preferred-device

Libusb preferred device

--- 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;
--- a/src/usb_audio.c
+++ b/src/usb_audio.c
@@ -169,7 +169,6 @@
     if (rc < 0) {
       SDL_Log("Error cancelling transfer: %s\n", libusb_error_name(rc));
     }
-    SDL_free(xfr[i]->buffer);
   }
 
   SDL_Log("Freeing interface %d", IFACE_NUM);
--