shithub: m8c

Download patch

ref: c7a3eb260734ba7f837fbcd75d0f2fed0ee6fd1f
parent: f7747ed108d2f4e3adab262ea8e768d2f21bfd36
author: Maido Käära <maido@producement.com>
date: Sat Jan 28 10:02:36 EST 2023

Separate libusb and libserial implementations

--- a/serial.c
+++ b/serial.c
@@ -4,6 +4,8 @@
 // Contains portions of code from libserialport's examples released to the
 // public domain
 
+#ifndef USE_LIBUSB
+#include <libserialport.h>
 #include <SDL.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -11,293 +13,6 @@
 #include <unistd.h>
 
 #include "serial.h"
-
-#ifdef USE_LIBUSB
-
-#include <libusb.h>
-
-static int ep_out_addr = 0x03;
-static int ep_in_addr = 0x83;
-
-#define ACM_CTRL_DTR   0x01
-#define ACM_CTRL_RTS   0x02
-
-usb_callback_t init_callback = NULL;
-usb_callback_t destroy_callback = NULL;
-libusb_device_handle *devh = NULL;
-
-void set_usb_init_callback(usb_callback_t callback) {
-    init_callback = callback;
-}
-
-void set_usb_destroy_callback(usb_callback_t callback) {
-    destroy_callback = callback;
-}
-
-int blocking_write(void *buf,
-                   int count, unsigned int timeout_ms) {
-    int actual_length;
-    int rc;
-    rc = libusb_bulk_transfer(devh, ep_out_addr, buf, count,
-                         &actual_length, timeout_ms);
-    if (rc < 0) {
-        SDL_Log("Error while sending char: %s", libusb_error_name(rc));
-        return -1;
-    }
-    return actual_length;
-}
-
-int serial_read(uint8_t *serial_buf, int count) {
-    int actual_length;
-    int rc = libusb_bulk_transfer(devh, ep_in_addr, serial_buf, count, &actual_length,
-                                  10);
-    if (rc == LIBUSB_ERROR_TIMEOUT) {
-        return 0;
-    } else if (rc < 0) {
-        SDL_Log("Error while waiting for char: %s", libusb_error_name(rc));
-        return -1;
-    }
-
-    return actual_length;
-}
-
-int check_serial_port() {
-    // Reading will fail anyway when the device is not present anymore
-    return 1;
-}
-
-int init_interface() {
-
-    if (devh == NULL) {
-        SDL_Log("Device not initialised!");
-        return 0;
-    }
-
-    int rc;
-
-    for (int if_num = 0; if_num < 2; if_num++) {
-        if (libusb_kernel_driver_active(devh, if_num)) {
-            SDL_Log("Detaching kernel driver for interface %d", if_num);
-            libusb_detach_kernel_driver(devh, if_num);
-        }
-        rc = libusb_claim_interface(devh, if_num);
-        if (rc < 0) {
-            SDL_Log("Error claiming interface: %s", libusb_error_name(rc));
-            return 0;
-        }
-    }
-
-    /* Start configuring the device:
-     * - set line state
-     */
-    SDL_Log("Setting line state");
-    rc = libusb_control_transfer(devh, 0x21, 0x22, ACM_CTRL_DTR | ACM_CTRL_RTS,
-                                 0, NULL, 0, 0);
-    if (rc < 0) {
-        SDL_Log("Error during control transfer: %s", libusb_error_name(rc));
-        return 0;
-    }
-
-    /* - set line encoding: here 115200 8N1
-     * 115200 = 0x01C200 ~> 0x00, 0xC2, 0x01, 0x00 in little endian
-     */
-    SDL_Log("Set line encoding");
-    unsigned char encoding[] = {0x00, 0xC2, 0x01, 0x00, 0x00, 0x00, 0x08};
-    rc = libusb_control_transfer(devh, 0x21, 0x20, 0, 0, encoding,
-                                 sizeof(encoding), 0);
-    if (rc < 0) {
-        SDL_Log("Error during control transfer: %s", libusb_error_name(rc));
-        return 0;
-    }
-
-    return 1;
-}
-
-int init_serial_with_file_descriptor(int file_descriptor) {
-    SDL_Log("Initialising serial with file descriptor");
-
-    if (file_descriptor <= 0) {
-        SDL_Log("Invalid file descriptor: %d", file_descriptor);
-        return 0;
-    }
-
-    int r;
-    r = libusb_set_option(NULL, LIBUSB_OPTION_NO_DEVICE_DISCOVERY, NULL);
-    if (r != LIBUSB_SUCCESS) {
-        SDL_Log("libusb_set_option failed: %s", libusb_error_name(r));
-        return 0;
-    }
-    r = libusb_init(NULL);
-    if (r < 0) {
-        SDL_Log("libusb_init failed: %s", libusb_error_name(r));
-        return 0;
-    }
-    r = libusb_wrap_sys_device(NULL, (intptr_t) file_descriptor, &devh);
-    if (r < 0) {
-        SDL_Log("libusb_wrap_sys_device failed: %s", libusb_error_name(r));
-        return 0;
-    } else if (devh == NULL) {
-        SDL_Log("libusb_wrap_sys_device returned invalid handle");
-        return 0;
-    }
-    SDL_Log("USB device init success");
-
-    if (init_callback != NULL) {
-        r = init_callback(devh);
-
-        if (r < 0) {
-            SDL_Log("Init callback failed: %d", r);
-            return 0;
-        }
-    }
-
-    return init_interface();
-}
-
-int init_serial(int verbose) {
-
-    if (devh != NULL) {
-        return 1;
-    }
-
-    int r;
-    r = libusb_init(NULL);
-    if (r < 0) {
-        SDL_Log("libusb_init failed: %s", libusb_error_name(r));
-        return 0;
-    }
-    devh = libusb_open_device_with_vid_pid(NULL, 0x16c0, 0x048a);
-    if (devh == NULL) {
-        SDL_Log("libusb_open_device_with_vid_pid returned invalid handle");
-        return 0;
-    }
-    SDL_Log("USB device init success");
-
-    if (init_callback != NULL) {
-        r = init_callback(devh);
-
-        if (r < 0) {
-            SDL_Log("Init callback failed: %d", r);
-            return 0;
-        }
-    }
-
-    return init_interface();
-}
-
-int reset_display() {
-    SDL_Log("Reset display\n");
-    uint8_t buf[2];
-    int result;
-
-    buf[0] = 0x45;
-    buf[1] = 0x52;
-
-    result = blocking_write(buf, 2, 5);
-    if (result != 2) {
-        SDL_LogError(SDL_LOG_CATEGORY_SYSTEM, "Error resetting M8 display, code %d",
-                     result);
-        return 0;
-    }
-    return 1;
-}
-
-int enable_and_reset_display() {
-    uint8_t buf[1];
-    int result;
-
-    SDL_Log("Enabling and resetting M8 display\n");
-
-    buf[0] = 0x44;
-    result = blocking_write(buf, 1, 5);
-    if (result != 1) {
-        SDL_LogError(SDL_LOG_CATEGORY_SYSTEM, "Error enabling M8 display, code %d",
-                     result);
-        return 0;
-    }
-
-    SDL_Delay(5);
-    result = reset_display();
-    if (result == 1)
-        return 1;
-    else
-        return 0;
-}
-
-int disconnect() {
-
-    char buf[1] = {'D'};
-    int result;
-
-    if (destroy_callback != NULL) {
-        result = destroy_callback(devh);
-
-        if (result < 0) {
-            SDL_Log("Destroy callback failed: %d", result);
-            return result;
-        }
-    }
-
-    SDL_Log("Disconnecting M8\n");
-
-    result = blocking_write(buf, 1, 5);
-    if (result != 1) {
-        SDL_LogError(SDL_LOG_CATEGORY_SYSTEM, "Error sending disconnect, code %d",
-                     result);
-        return -1;
-    }
-
-    int rc;
-
-    for (int if_num = 0; if_num < 2; if_num++) {
-        rc = libusb_release_interface(devh, if_num);
-        if (rc < 0) {
-            SDL_Log("Error releasing interface: %s", libusb_error_name(rc));
-            return 0;
-        }
-    }
-
-    if (devh != NULL) {
-        libusb_close(devh);
-    }
-
-    libusb_exit(NULL);
-
-    return 1;
-}
-
-int send_msg_controller(uint8_t input) {
-    char buf[2] = {'C', input};
-    int nbytes = 2;
-    int result;
-    result = blocking_write(buf, nbytes, 5);
-    if (result != nbytes) {
-        SDL_LogError(SDL_LOG_CATEGORY_SYSTEM, "Error sending input, code %d",
-                     result);
-        return -1;
-    }
-    return 1;
-}
-
-int send_msg_keyjazz(uint8_t note, uint8_t velocity) {
-    if (velocity > 0x7F)
-        velocity = 0x7F;
-    char buf[3] = {'K', note, velocity};
-    int nbytes = 3;
-    int result;
-    result = blocking_write(buf, nbytes, 5);
-    if (result != nbytes) {
-        SDL_LogError(SDL_LOG_CATEGORY_SYSTEM, "Error sending keyjazz, code %d",
-                     result);
-        return -1;
-    }
-
-    return 1;
-}
-
-
-#else
-#include <libserialport.h>
 
 struct sp_port *m8_port = NULL;
 
--- /dev/null
+++ b/usb.c
@@ -1,0 +1,298 @@
+// Copyright 2021 Jonne Kokkonen
+// Released under the MIT licence, https://opensource.org/licenses/MIT
+
+// Contains portions of code from libserialport's examples released to the
+// public domain
+#ifdef USE_LIBUSB
+
+#include <SDL.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <libusb.h>
+
+#include "serial.h"
+
+
+static int ep_out_addr = 0x03;
+static int ep_in_addr = 0x83;
+
+#define ACM_CTRL_DTR   0x01
+#define ACM_CTRL_RTS   0x02
+
+usb_callback_t init_callback = NULL;
+usb_callback_t destroy_callback = NULL;
+libusb_device_handle *devh = NULL;
+
+void set_usb_init_callback(usb_callback_t callback) {
+    init_callback = callback;
+}
+
+void set_usb_destroy_callback(usb_callback_t callback) {
+    destroy_callback = callback;
+}
+
+int blocking_write(void *buf,
+                   int count, unsigned int timeout_ms) {
+    int actual_length;
+    int rc;
+    rc = libusb_bulk_transfer(devh, ep_out_addr, buf, count,
+                         &actual_length, timeout_ms);
+    if (rc < 0) {
+        SDL_Log("Error while sending char: %s", libusb_error_name(rc));
+        return -1;
+    }
+    return actual_length;
+}
+
+int serial_read(uint8_t *serial_buf, int count) {
+    int actual_length;
+    int rc = libusb_bulk_transfer(devh, ep_in_addr, serial_buf, count, &actual_length,
+                                  10);
+    if (rc == LIBUSB_ERROR_TIMEOUT) {
+        return 0;
+    } else if (rc < 0) {
+        SDL_Log("Error while waiting for char: %s", libusb_error_name(rc));
+        return -1;
+    }
+
+    return actual_length;
+}
+
+int check_serial_port() {
+    // Reading will fail anyway when the device is not present anymore
+    return 1;
+}
+
+int init_interface() {
+
+    if (devh == NULL) {
+        SDL_Log("Device not initialised!");
+        return 0;
+    }
+
+    int rc;
+
+    for (int if_num = 0; if_num < 2; if_num++) {
+        if (libusb_kernel_driver_active(devh, if_num)) {
+            SDL_Log("Detaching kernel driver for interface %d", if_num);
+            libusb_detach_kernel_driver(devh, if_num);
+        }
+        rc = libusb_claim_interface(devh, if_num);
+        if (rc < 0) {
+            SDL_Log("Error claiming interface: %s", libusb_error_name(rc));
+            return 0;
+        }
+    }
+
+    /* Start configuring the device:
+     * - set line state
+     */
+    SDL_Log("Setting line state");
+    rc = libusb_control_transfer(devh, 0x21, 0x22, ACM_CTRL_DTR | ACM_CTRL_RTS,
+                                 0, NULL, 0, 0);
+    if (rc < 0) {
+        SDL_Log("Error during control transfer: %s", libusb_error_name(rc));
+        return 0;
+    }
+
+    /* - set line encoding: here 115200 8N1
+     * 115200 = 0x01C200 ~> 0x00, 0xC2, 0x01, 0x00 in little endian
+     */
+    SDL_Log("Set line encoding");
+    unsigned char encoding[] = {0x00, 0xC2, 0x01, 0x00, 0x00, 0x00, 0x08};
+    rc = libusb_control_transfer(devh, 0x21, 0x20, 0, 0, encoding,
+                                 sizeof(encoding), 0);
+    if (rc < 0) {
+        SDL_Log("Error during control transfer: %s", libusb_error_name(rc));
+        return 0;
+    }
+
+    return 1;
+}
+
+int init_serial_with_file_descriptor(int file_descriptor) {
+    SDL_Log("Initialising serial with file descriptor");
+
+    if (file_descriptor <= 0) {
+        SDL_Log("Invalid file descriptor: %d", file_descriptor);
+        return 0;
+    }
+
+    int r;
+    r = libusb_set_option(NULL, LIBUSB_OPTION_NO_DEVICE_DISCOVERY, NULL);
+    if (r != LIBUSB_SUCCESS) {
+        SDL_Log("libusb_set_option failed: %s", libusb_error_name(r));
+        return 0;
+    }
+    r = libusb_init(NULL);
+    if (r < 0) {
+        SDL_Log("libusb_init failed: %s", libusb_error_name(r));
+        return 0;
+    }
+    r = libusb_wrap_sys_device(NULL, (intptr_t) file_descriptor, &devh);
+    if (r < 0) {
+        SDL_Log("libusb_wrap_sys_device failed: %s", libusb_error_name(r));
+        return 0;
+    } else if (devh == NULL) {
+        SDL_Log("libusb_wrap_sys_device returned invalid handle");
+        return 0;
+    }
+    SDL_Log("USB device init success");
+
+    if (init_callback != NULL) {
+        r = init_callback(devh);
+
+        if (r < 0) {
+            SDL_Log("Init callback failed: %d", r);
+            return 0;
+        }
+    }
+
+    return init_interface();
+}
+
+int init_serial(int verbose) {
+
+    if (devh != NULL) {
+        return 1;
+    }
+
+    int r;
+    r = libusb_init(NULL);
+    if (r < 0) {
+        SDL_Log("libusb_init failed: %s", libusb_error_name(r));
+        return 0;
+    }
+    devh = libusb_open_device_with_vid_pid(NULL, 0x16c0, 0x048a);
+    if (devh == NULL) {
+        SDL_Log("libusb_open_device_with_vid_pid returned invalid handle");
+        return 0;
+    }
+    SDL_Log("USB device init success");
+
+    if (init_callback != NULL) {
+        r = init_callback(devh);
+
+        if (r < 0) {
+            SDL_Log("Init callback failed: %d", r);
+            return 0;
+        }
+    }
+
+    return init_interface();
+}
+
+int reset_display() {
+    SDL_Log("Reset display\n");
+    uint8_t buf[2];
+    int result;
+
+    buf[0] = 0x45;
+    buf[1] = 0x52;
+
+    result = blocking_write(buf, 2, 5);
+    if (result != 2) {
+        SDL_LogError(SDL_LOG_CATEGORY_SYSTEM, "Error resetting M8 display, code %d",
+                     result);
+        return 0;
+    }
+    return 1;
+}
+
+int enable_and_reset_display() {
+    uint8_t buf[1];
+    int result;
+
+    SDL_Log("Enabling and resetting M8 display\n");
+
+    buf[0] = 0x44;
+    result = blocking_write(buf, 1, 5);
+    if (result != 1) {
+        SDL_LogError(SDL_LOG_CATEGORY_SYSTEM, "Error enabling M8 display, code %d",
+                     result);
+        return 0;
+    }
+
+    SDL_Delay(5);
+    result = reset_display();
+    if (result == 1)
+        return 1;
+    else
+        return 0;
+}
+
+int disconnect() {
+
+    char buf[1] = {'D'};
+    int result;
+
+    if (destroy_callback != NULL) {
+        result = destroy_callback(devh);
+
+        if (result < 0) {
+            SDL_Log("Destroy callback failed: %d", result);
+            return result;
+        }
+    }
+
+    SDL_Log("Disconnecting M8\n");
+
+    result = blocking_write(buf, 1, 5);
+    if (result != 1) {
+        SDL_LogError(SDL_LOG_CATEGORY_SYSTEM, "Error sending disconnect, code %d",
+                     result);
+        return -1;
+    }
+
+    int rc;
+
+    for (int if_num = 0; if_num < 2; if_num++) {
+        rc = libusb_release_interface(devh, if_num);
+        if (rc < 0) {
+            SDL_Log("Error releasing interface: %s", libusb_error_name(rc));
+            return 0;
+        }
+    }
+
+    if (devh != NULL) {
+        libusb_close(devh);
+    }
+
+    libusb_exit(NULL);
+
+    return 1;
+}
+
+int send_msg_controller(uint8_t input) {
+    char buf[2] = {'C', input};
+    int nbytes = 2;
+    int result;
+    result = blocking_write(buf, nbytes, 5);
+    if (result != nbytes) {
+        SDL_LogError(SDL_LOG_CATEGORY_SYSTEM, "Error sending input, code %d",
+                     result);
+        return -1;
+    }
+    return 1;
+}
+
+int send_msg_keyjazz(uint8_t note, uint8_t velocity) {
+    if (velocity > 0x7F)
+        velocity = 0x7F;
+    char buf[3] = {'K', note, velocity};
+    int nbytes = 3;
+    int result;
+    result = blocking_write(buf, nbytes, 5);
+    if (result != nbytes) {
+        SDL_LogError(SDL_LOG_CATEGORY_SYSTEM, "Error sending keyjazz, code %d",
+                     result);
+        return -1;
+    }
+
+    return 1;
+}
+
+
+
--