ref: a365133b6207e8a5e227b4d3cebf48df0fa9a0f6
parent: 1f73f4f2a5855366cd64856cad764f984ebf956b
author: Maido Käära <maido@producement.com>
date: Thu Dec 8 17:59:48 EST 2022
Refactor serial port usage - Move all references to libserialport to serial.c - Move the serial port instance to serial.c and don't expose it - Define USE_LIBSERIALPORT flag to turn libserialport dependent code on/off
--- /dev/null
+++ b/.editorconfig
@@ -1,0 +1,18 @@
+# EditorConfig is awesome: https://EditorConfig.org
+
+# top-most EditorConfig file
+root = true
+
+# Unix-style newlines with a newline ending every file
+[*]
+end_of_line = lf
+insert_final_newline = true
+
+# 2 space indentation
+[*.c]
+indent_style = space
+indent_size = 2
+
+# Tab indentation (no size specified)
+[Makefile]
+indent_style = tab
\ No newline at end of file
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,8 @@
#Set all your object files (the object files of all the .c files in your project, e.g. main.o my_sub_functions.o )
-OBJ = main.o serial.o slip.o command.o write.o render.o ini.o config.o input.o font.o fx_cube.o
+OBJ = main.o serial.o slip.o command.o render.o ini.o config.o input.o font.o fx_cube.o
#Set any dependant header files so that if they are edited they cause a complete re-compile (e.g. main.h some_subfunctions.h some_definitions_file.h ), or leave blank
-DEPS = serial.h slip.h command.h write.h render.h ini.h config.h input.h fx_cube.h
+DEPS = serial.h slip.h command.h render.h ini.h config.h input.h fx_cube.h
#Any special libraries you are using in your project (e.g. -lbcm2835 -lrt `pkg-config --libs gtk+-3.0` ), or leave blank
INCLUDES = $(shell pkg-config --libs sdl2 libserialport)
@@ -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.
+local_CFLAGS = $(CFLAGS) $(shell pkg-config --cflags sdl2 libserialport) -Wall -O2 -pipe -I. -DUSE_LIBSERIALPORT
#Set the compiler you are using ( gcc for C or g++ for C++ )
CC = gcc
--- a/input.c
+++ b/input.c
@@ -7,7 +7,6 @@
#include "config.h"
#include "input.h"
#include "render.h"
-#include "write.h"
#define MAX_CONTROLLERS 4
@@ -365,12 +364,12 @@
// Read special case game controller buttons quit and reset
for (int gc = 0; gc < num_joysticks; gc++) {- if (SDL_GameControllerGetButton(game_controllers[gc], conf->gamepad_quit) &&
- (SDL_GameControllerGetButton(game_controllers[gc], conf->gamepad_select) ||
+ if (SDL_GameControllerGetButton(game_controllers[gc], conf->gamepad_quit) &&
+ (SDL_GameControllerGetButton(game_controllers[gc], conf->gamepad_select) ||
SDL_GameControllerGetAxis(game_controllers[gc], conf->gamepad_analog_axis_select)))
key = (input_msg_s){special, msg_quit};- else if (SDL_GameControllerGetButton(game_controllers[gc], conf->gamepad_reset) &&
- (SDL_GameControllerGetButton(game_controllers[gc], conf->gamepad_select) ||
+ else if (SDL_GameControllerGetButton(game_controllers[gc], conf->gamepad_reset) &&
+ (SDL_GameControllerGetButton(game_controllers[gc], conf->gamepad_select) ||
SDL_GameControllerGetAxis(game_controllers[gc], conf->gamepad_analog_axis_select)))
key = (input_msg_s){special, msg_reset_display};}
@@ -394,7 +393,7 @@
if (event.window.event == SDL_WINDOWEVENT_RESIZED)
{ SDL_Log("Resizing window...");- key = (input_msg_s){special, msg_reset_display}; + key = (input_msg_s){special, msg_reset_display};}
break;
--- a/main.c
+++ b/main.c
@@ -6,7 +6,6 @@
// #define DEBUG_MSG
#include <SDL.h>
-#include <libserialport.h>
#include <signal.h>
#include "command.h"
@@ -15,7 +14,6 @@
#include "render.h"
#include "serial.h"
#include "slip.h"
-#include "write.h"
// maximum amount of bytes to read from the serial in one read()
#define serial_read_size 324
@@ -28,10 +26,8 @@
// Handles CTRL+C / SIGINT
void intHandler(int dummy) { run = QUIT; }-void close_serial_port(struct sp_port *port) {- disconnect(port);
- sp_close(port);
- sp_free_port(port);
+void close_serial_port() {+ disconnect();
}
int main(int argc, char *argv[]) {@@ -56,7 +52,6 @@
};
static slip_handler_s slip;
- struct sp_port *port = NULL;
uint8_t prev_input = 0;
uint8_t prev_note = 0;
@@ -69,8 +64,7 @@
// First device detection to avoid SDL init if it isn't necessary
if (conf.wait_for_device == 0) {- port = init_serial(1);
- if (port == NULL) {+ if (!init_serial(1)) {free(serial_buf);
return -1;
}
@@ -89,11 +83,10 @@
// main loop begin
do {- if (port == NULL)
- port = init_serial(1);
- if (port != NULL) {+ int port_inited = init_serial(1);
+ if (port_inited) {int result;
- result = enable_and_reset_display(port);
+ result = enable_and_reset_display();
if (result == 1) {run = RUN;
} else {@@ -108,7 +101,7 @@
static uint32_t ticks_poll_device = 0;
static uint32_t ticks_update_screen = 0;
- if (port == NULL)
+ if (!port_inited)
screensaver_init();
while (run == WAIT_FOR_DEVICE) {@@ -126,11 +119,10 @@
}
// Poll for M8 device every second
- if (!port && (SDL_GetTicks() - ticks_poll_device > 1000)) {+ if (!port_inited && (SDL_GetTicks() - ticks_poll_device > 1000)) {ticks_poll_device = SDL_GetTicks();
- port = init_serial(0);
- if (run == WAIT_FOR_DEVICE && port != NULL) {- int result = enable_and_reset_display(port);
+ if (run == WAIT_FOR_DEVICE && init_serial(0)) {+ int result = enable_and_reset_display();
SDL_Delay(100);
// Device was found; enable display and proceed to the main loop
if (result == 1) {@@ -149,7 +141,7 @@
} else {// classic startup behaviour, exit if device is not found
- if (port == NULL) {+ if (!port_inited) {close_game_controllers();
close_renderer();
SDL_Quit();
@@ -168,16 +160,16 @@
case normal:
if (input.value != prev_input) {prev_input = input.value;
- send_msg_controller(port, input.value);
+ send_msg_controller(input.value);
}
break;
case keyjazz:
if (input.value != 0) { if (input.eventType == SDL_KEYDOWN && input.value != prev_input) {- send_msg_keyjazz(port, input.value, input.value2);
+ send_msg_keyjazz(input.value, input.value2);
prev_note = input.value;
} else if (input.eventType == SDL_KEYUP && input.value == prev_note) {- send_msg_keyjazz(port, 0xFF, 0);
+ send_msg_keyjazz(0xFF, 0);
}
}
prev_input = input.value;
@@ -191,7 +183,7 @@
run = 0;
break;
case msg_reset_display:
- reset_display(port);
+ reset_display();
break;
default:
break;
@@ -203,7 +195,7 @@
while (1) {// read serial port
int bytes_read =
- sp_nonblocking_read(port, serial_buf, serial_read_size);
+ serial_read(serial_buf, serial_read_size);
if (bytes_read < 0) {SDL_LogCritical(SDL_LOG_CATEGORY_ERROR, "Error %d reading serial. \n",
(int)bytes_read);
@@ -220,7 +212,7 @@
int n = slip_read_byte(&slip, *(cur++));
if (n != SLIP_NO_ERROR) { if (n == SLIP_ERROR_INVALID_PACKET) {- reset_display(port);
+ reset_display();
} else {SDL_LogError(SDL_LOG_CATEGORY_ERROR, "SLIP error %d\n", n);
}
@@ -233,13 +225,12 @@
zerobyte_packets = 0;
// try opening the serial port to check if it's alive
- if (check_serial_port(port)) {+ if (check_serial_port()) {// the device is still there, carry on
break;
} else {run = WAIT_FOR_DEVICE;
- close_serial_port(port);
- port = NULL;
+ close_serial_port();
/* we'll make one more loop to see if the device is still there
* but just sending zero bytes. if it doesn't get detected when
* resetting the port, it will disconnect */
@@ -258,7 +249,7 @@
SDL_Log("Shutting down\n");close_game_controllers();
close_renderer();
- close_serial_port(port);
+ close_serial_port();
free(serial_buf);
SDL_Quit();
return 0;
--- a/serial.c
+++ b/serial.c
@@ -5,24 +5,30 @@
// public domain
#include <SDL_log.h>
-#include <libserialport.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include "SDL_timer.h"
+#include <unistd.h>
#include "serial.h"
+#ifdef USE_LIBSERIALPORT
+#include <libserialport.h>
+
+struct sp_port *m8_port = NULL;
+
// Helper function for error handling
static int check(enum sp_return result);
-static int detect_m8_serial_device(struct sp_port *port) {+static int detect_m8_serial_device(struct sp_port *m8_port) {// Check the connection method - we want USB serial devices
- enum sp_transport transport = sp_get_port_transport(port);
+ enum sp_transport transport = sp_get_port_transport(m8_port);
if (transport == SP_TRANSPORT_USB) {// Get the USB vendor and product IDs.
int usb_vid, usb_pid;
- sp_get_port_usb_vid_pid(port, &usb_vid, &usb_pid);
+ sp_get_port_usb_vid_pid(m8_port, &usb_vid, &usb_pid);
if (usb_vid == 0x16C0 && usb_pid == 0x048A)
return 1;
@@ -32,7 +38,7 @@
}
// Checks for connected devices and whether the specified device still exists
-int check_serial_port(struct sp_port *m8_port) {+int check_serial_port() {int device_found = 0;
@@ -65,10 +71,12 @@
}
-struct sp_port *init_serial(int verbose) {+int init_serial(int verbose) {+ if(m8_port != NULL) {+ return 1;
+ }
/* A pointer to a null-terminated array of pointers to
* struct sp_port, which will contain the ports found.*/
- struct sp_port *m8_port = NULL;
struct sp_port **port_list;
if (verbose)
@@ -103,33 +111,33 @@
result = sp_open(m8_port, SP_MODE_READ_WRITE);
if (check(result) != SP_OK)
- return NULL;
+ return 0;
result = sp_set_baudrate(m8_port, 115200);
if (check(result) != SP_OK)
- return NULL;
+ return 0;
result = sp_set_bits(m8_port, 8);
if (check(result) != SP_OK)
- return NULL;
+ return 0;
result = sp_set_parity(m8_port, SP_PARITY_NONE);
if (check(result) != SP_OK)
- return NULL;
+ return 0;
result = sp_set_stopbits(m8_port, 1);
if (check(result) != SP_OK)
- return NULL;
+ return 0;
result = sp_set_flowcontrol(m8_port, SP_FLOWCONTROL_NONE);
if (check(result) != SP_OK)
- return NULL;
+ return 0;
} else {if (verbose)
SDL_LogCritical(SDL_LOG_CATEGORY_SYSTEM, "Cannot find a M8.\n");
}
- return (m8_port);
+ return 1;
}
// Helper function for error handling.
@@ -160,3 +168,94 @@
}
return result;
}
+
+int reset_display() {+ SDL_Log("Reset display\n");+ uint8_t buf[2];
+ int result;
+
+ buf[0] = 0x45;
+ buf[1] = 0x52;
+
+ result = sp_blocking_write(m8_port, 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 = sp_blocking_write(m8_port, 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 = sp_blocking_write(m8_port, buf, 1, 5);
+ if (result != 1) {+ SDL_LogError(SDL_LOG_CATEGORY_SYSTEM, "Error sending disconnect, code %d",
+ result);
+ return -1;
+ }
+ sp_close(m8_port);
+ sp_free_port(m8_port);
+ m8_port = NULL;
+ return 1;
+}
+
+int serial_read(uint8_t *serial_buf, int count) {+ return sp_nonblocking_read(m8_port, serial_buf, count);
+}
+
+int send_msg_controller(uint8_t input) {+ char buf[2] = {'C', input};+ size_t nbytes = 2;
+ int result;
+ result = sp_blocking_write(m8_port, 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};+ size_t nbytes = 3;
+ int result;
+ result = sp_blocking_write(m8_port, buf, nbytes, 5);
+ if (result != nbytes) {+ SDL_LogError(SDL_LOG_CATEGORY_SYSTEM, "Error sending keyjazz, code %d",
+ result);
+ return -1;
+ }
+
+ return 1;
+}
+#endif
--- a/serial.h
+++ b/serial.h
@@ -4,9 +4,13 @@
#ifndef _SERIAL_H_
#define _SERIAL_H_
-#include <libserialport.h>
+int init_serial(int verbose);
+int check_serial_port();
+int reset_display();
+int enable_and_reset_display();
+int disconnect();
+int serial_read(uint8_t *serial_buf, int count);
+int send_msg_controller(uint8_t input);
+int send_msg_keyjazz(uint8_t note, uint8_t velocity);
-struct sp_port *init_serial(int verbose);
-int check_serial_port(struct sp_port *m8_port);
-
-#endif
\ No newline at end of file
+#endif
--- a/write.c
+++ /dev/null
@@ -1,92 +1,0 @@
-// Copyright 2021 Jonne Kokkonen
-// Released under the MIT licence, https://opensource.org/licenses/MIT
-
-#include "SDL_timer.h"
-#include <SDL_log.h>
-#include <libserialport.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <unistd.h>
-
-int reset_display(struct sp_port *port) {- SDL_Log("Reset display\n");- uint8_t buf[2];
- int result;
-
- buf[0] = 0x45;
- buf[1] = 0x52;
-
- result = sp_blocking_write(port, 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(struct sp_port *port) {- uint8_t buf[1];
- int result;
-
- SDL_Log("Enabling and resetting M8 display\n");-
- buf[0] = 0x44;
- result = sp_blocking_write(port, 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(port);
- if (result == 1)
- return 1;
- else
- return 0;
-}
-
-int disconnect(struct sp_port *port) {- char buf[1] = {'D'};- int result;
-
- SDL_Log("Disconnecting M8\n");-
- result = sp_blocking_write(port, 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(struct sp_port *port, uint8_t input) {- char buf[2] = {'C', input};- size_t nbytes = 2;
- int result;
- result = sp_blocking_write(port, 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(struct sp_port *port, uint8_t note, uint8_t velocity) {- if (velocity > 0x7F)
- velocity = 0x7F;
- char buf[3] = {'K', note, velocity};- size_t nbytes = 3;
- int result;
- result = sp_blocking_write(port, buf, nbytes, 5);
- if (result != nbytes) {- SDL_LogError(SDL_LOG_CATEGORY_SYSTEM, "Error sending keyjazz, code %d",
- result);
- return -1;
- }
-
- return 1;
-}
--- a/write.h
+++ /dev/null
@@ -1,16 +1,0 @@
-// Copyright 2021 Jonne Kokkonen
-// Released under the MIT licence, https://opensource.org/licenses/MIT
-
-#ifndef WRITE_H_
-#define WRITE_H_
-
-#include <stdint.h>
-#include <libserialport.h>
-
-int reset_display(struct sp_port *port);
-int enable_and_reset_display(struct sp_port *port);
-int disconnect(struct sp_port *port);
-int send_msg_controller(struct sp_port *port, uint8_t input);
-int send_msg_keyjazz(struct sp_port *port, uint8_t note, uint8_t velocity);
-
-#endif
\ No newline at end of file
--
⑨