shithub: m8c

Download patch

ref: 3aefa632b813b36869384d1639f38f63ce99349e
parent: a365133b6207e8a5e227b4d3cebf48df0fa9a0f6
author: Maido Käära <maido@producement.com>
date: Fri Dec 9 06:42:58 EST 2022

Add initial libusb support

--- /dev/null
+++ b/Android.mk
@@ -1,0 +1,17 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := m8c
+
+LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.c)
+
+LOCAL_EXPORT_C_INCLUDES := $(wildcard $(LOCAL_PATH)/*.h)
+
+LOCAL_CFLAGS += -DUSE_LIBUSB
+
+LOCAL_SHARED_LIBRARIES := usb-1.0 SDL2
+
+LOCAL_LDLIBS := -lGLESv1_CM -lGLESv2 -lOpenSLES -llog -landroid
+
+include $(BUILD_SHARED_LIBRARY)
--- a/Makefile
+++ b/Makefile
@@ -10,7 +10,7 @@
 
 
 #Set any compiler flags you want to use (e.g. -I/usr/include/somefolder `pkg-config --cflags gtk+-3.0` ), or leave blank
-local_CFLAGS = $(CFLAGS) $(shell pkg-config --cflags sdl2 libserialport) -Wall -O2 -pipe -I. -DUSE_LIBSERIALPORT
+local_CFLAGS = $(CFLAGS) $(shell pkg-config --cflags sdl2 libserialport) -Wall -O2 -pipe -I.
 
 #Set the compiler you are using ( gcc for C or g++ for C++ )
 CC = gcc
--- a/inprint2.c
+++ b/inprint2.c
@@ -2,7 +2,7 @@
 // Released into public domain.
 // Modified to support adding a background to text.
 
-#include <SDL2/SDL.h>
+#include <SDL.h>
 
 #include "inline_font.h" /* Actual font data */
 
--- a/main.c
+++ b/main.c
@@ -15,9 +15,6 @@
 #include "serial.h"
 #include "slip.h"
 
-// maximum amount of bytes to read from the serial in one read()
-#define serial_read_size 324
-
 enum state { QUIT, WAIT_FOR_DEVICE, RUN };
 
 enum state run = WAIT_FOR_DEVICE;
--- a/serial.c
+++ b/serial.c
@@ -13,7 +13,218 @@
 
 #include "serial.h"
 
-#ifdef USE_LIBSERIALPORT
+#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
+
+libusb_device_handle *devh = NULL;
+int file_descriptor = -1;
+
+void set_file_descriptor(int fd) {
+    file_descriptor = fd;
+    if (fd == -1) {
+        devh = NULL;
+    }
+}
+
+int blocking_write(void *buf,
+                   int count, unsigned int timeout_ms) {
+    int actual_length;
+    if (libusb_bulk_transfer(devh, ep_out_addr, buf, count,
+                             &actual_length, timeout_ms) < 0) {
+        SDL_Log("Error while sending char\n");
+        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: %d\n", rc);
+        return -1;
+    }
+
+    return actual_length;
+}
+
+int check_serial_port() {
+    libusb_device *device;
+    device = libusb_get_device(devh);
+    return device != NULL;
+}
+
+int handle_from_file_descriptor(int fileDescriptor) {
+    libusb_context *ctx = NULL;
+    int r;
+    r = libusb_set_option(ctx, LIBUSB_OPTION_NO_DEVICE_DISCOVERY, NULL);
+    if (r != LIBUSB_SUCCESS) {
+        SDL_Log("libusb_init failed: %d\n", r);
+        return r;
+    }
+    r = libusb_init(&ctx);
+    if (r < 0) {
+        SDL_Log("libusb_init failed: %d\n", r);
+        return r;
+    }
+    r = libusb_wrap_sys_device(ctx, (intptr_t) fileDescriptor, &devh);
+    if (r < 0) {
+        SDL_Log("libusb_wrap_sys_device failed: %d\n", r);
+        return r;
+    } else if (devh == NULL) {
+        SDL_Log("libusb_wrap_sys_device returned invalid handle\n");
+        return r;
+    }
+    SDL_Log("USB device init success");
+    return 0;
+}
+
+int init_serial(int verbose) {
+
+    if (devh != NULL) {
+        if (verbose)
+            SDL_Log("Device already initialised");
+        return 1;
+    }
+
+    if (file_descriptor == -1) {
+        SDL_LogError(SDL_LOG_CATEGORY_SYSTEM, "File descriptor was not set!\n");
+        abort();
+    }
+
+    if (verbose)
+        SDL_Log("Initialising USB device for %d", file_descriptor);
+
+    int rc;
+
+    rc = handle_from_file_descriptor(file_descriptor);
+
+    if (rc < 0) {
+        return rc;
+    }
+
+    /* 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\n",
+                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\n",
+                libusb_error_name(rc));
+        return 0;
+    }
+
+    return 1;
+}
+
+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;
+
+    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;
+    }
+    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;
@@ -259,3 +470,4 @@
   return 1;
 }
 #endif
+
--- a/serial.h
+++ b/serial.h
@@ -4,6 +4,15 @@
 #ifndef _SERIAL_H_
 #define _SERIAL_H_
 
+#ifdef USE_LIBUSB
+// Not sure about this value but it seems to work
+#define serial_read_size 512
+void set_file_descriptor(int fd);
+#else
+// maximum amount of bytes to read from the serial in one read()
+#define serial_read_size 324
+#endif
+
 int init_serial(int verbose);
 int check_serial_port();
 int reset_display();
--