shithub: m8c

Download patch

ref: cd4a24fc05afaf671ec7287a854d73b20f4fd3e9
parent: 7b749ed1b5949e36bd8ef1609cc5abec68c7df5b
author: Jonne Kokkonen <jonne.kokkonen@gmail.com>
date: Fri Jun 18 10:32:50 EDT 2021

add possibility to reset display manually, add automatic display reset on packet errors

--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,5 @@
 .vscode
 font.c
 build/
+compile_commands.json
+.clangd
--- a/README.md
+++ b/README.md
@@ -82,6 +82,7 @@
 * Alt + F4 = quit program
 * Delete = opt+edit (deletes a row)
 * Esc = toggle keyjazz on/off 
+* r / select+start+opt+edit = reset display (if glitches appear on the screen, use this)
 
 Keyjazz allows to enter notes with keyboard, oldschool tracker-style. The layout is two octaves, starting from keys Z and Q.
 When keyjazz is active, regular a/s/z/x keys are disabled.
--- a/command.c
+++ b/command.c
@@ -30,7 +30,7 @@
   SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "\n");
 }
 
-void process_command(uint8_t *data, uint32_t size) {
+int process_command(uint8_t *data, uint32_t size) {
 
   uint8_t recv_buf[size + 1];
 
@@ -47,15 +47,18 @@
           "Invalid draw rectangle packet: expected length %d, got %d\n",
           draw_rectangle_command_datalength, size);
       dump_packet(size, recv_buf);
+      return 0;
       break;
-    }
+    } else {
 
-    struct draw_rectangle_command rectcmd = {
-        {decodeInt16(recv_buf, 1), decodeInt16(recv_buf, 3)}, // position x/y
-        {decodeInt16(recv_buf, 5), decodeInt16(recv_buf, 7)}, // size w/h
-        {recv_buf[9], recv_buf[10], recv_buf[11]}};           // color r/g/b
+      struct draw_rectangle_command rectcmd = {
+          {decodeInt16(recv_buf, 1), decodeInt16(recv_buf, 3)}, // position x/y
+          {decodeInt16(recv_buf, 5), decodeInt16(recv_buf, 7)}, // size w/h
+          {recv_buf[9], recv_buf[10], recv_buf[11]}};           // color r/g/b
 
-    draw_rectangle(&rectcmd);
+      draw_rectangle(&rectcmd);
+      return 1;
+    }
 
     break;
 
@@ -67,16 +70,19 @@
           "Invalid draw character packet: expected length %d, got %d\n",
           draw_character_command_datalength, size);
       dump_packet(size, recv_buf);
+      return 0;
       break;
+    } else {
+
+      struct draw_character_command charcmd = {
+          recv_buf[1],                                          // char
+          {decodeInt16(recv_buf, 2), decodeInt16(recv_buf, 4)}, // position x/y
+          {recv_buf[6], recv_buf[7], recv_buf[8]},    // foreground r/g/b
+          {recv_buf[9], recv_buf[10], recv_buf[11]}}; // background r/g/b
+      draw_character(&charcmd);
+      return 1;
     }
 
-    struct draw_character_command charcmd = {
-        recv_buf[1],                                          // char
-        {decodeInt16(recv_buf, 2), decodeInt16(recv_buf, 4)}, // position x/y
-        {recv_buf[6], recv_buf[7], recv_buf[8]},    // foreground r/g/b
-        {recv_buf[9], recv_buf[10], recv_buf[11]}}; // background r/g/b
-    draw_character(&charcmd);
-
     break;
 
   case draw_oscilloscope_waveform_command:
@@ -91,18 +97,21 @@
           draw_oscilloscope_waveform_command_mindatalength,
           draw_oscilloscope_waveform_command_maxdatalength, size);
       dump_packet(size, recv_buf);
+      return 0;
       break;
-    }
+    } else {
 
-    struct draw_oscilloscope_waveform_command osccmd;
+      struct draw_oscilloscope_waveform_command osccmd;
 
-    osccmd.color =
-        (struct color){recv_buf[1], recv_buf[2], recv_buf[3]}; // color r/g/b
-    memcpy(osccmd.waveform, &recv_buf[4], size - 4);
+      osccmd.color =
+          (struct color){recv_buf[1], recv_buf[2], recv_buf[3]}; // color r/g/b
+      memcpy(osccmd.waveform, &recv_buf[4], size - 4);
 
-    osccmd.waveform_size = size - 4;
+      osccmd.waveform_size = size - 4;
 
-    draw_waveform(&osccmd);
+      draw_waveform(&osccmd);
+      return 1;
+    }
 
     break;
 
@@ -118,7 +127,7 @@
     } */
 
     // nothing is done with joypad key pressed packets for now
-
+    return 1;
     break;
 
   default:
@@ -125,7 +134,7 @@
 
     SDL_LogError(SDL_LOG_CATEGORY_ERROR, "Invalid packet\n");
     dump_packet(size, recv_buf);
-
+    return 1;
     break;
   }
 }
--- a/command.h
+++ b/command.h
@@ -51,6 +51,6 @@
 };
 
 
-void process_command(uint8_t *data, uint32_t size);
+int process_command(uint8_t *data, uint32_t size);
 
 #endif
\ No newline at end of file
--- a/input.c
+++ b/input.c
@@ -2,8 +2,6 @@
 // Released under the MIT licence, https://opensource.org/licenses/MIT
 
 #include <SDL2/SDL.h>
-#include <SDL2/SDL_events.h>
-#include <SDL2/SDL_gamecontroller.h>
 #include <stdio.h>
 
 #include "input.h"
@@ -44,7 +42,8 @@
   int controller_index = 0;
 
   SDL_Log("Looking for game controllers\n");
-  SDL_Delay(1); // Some controllers like XBone wired need a little while to get ready
+  SDL_Delay(
+      1); // Some controllers like XBone wired need a little while to get ready
   // Open all available game controllers
   for (int i = 0; i < num_joysticks; i++) {
     if (!SDL_IsGameController(i))
@@ -52,7 +51,8 @@
     if (controller_index >= MAX_CONTROLLERS)
       break;
     game_controllers[controller_index] = SDL_GameControllerOpen(i);
-    SDL_Log("Controller %d: %s",controller_index+1,SDL_GameControllerName(game_controllers[controller_index]));
+    SDL_Log("Controller %d: %s", controller_index + 1,
+            SDL_GameControllerName(game_controllers[controller_index]));
     controller_index++;
   }
 
@@ -227,6 +227,10 @@
     key.value = key_opt | key_edit;
     break;
 
+  case SDL_SCANCODE_R:
+    key = (input_msg_s){special, msg_reset_display};
+    break;
+
   default:
     key.value = 0;
     break;
@@ -288,6 +292,10 @@
 
   switch (event.type) {
 
+  case SDL_WINDOWEVENT_RESIZED:
+    key = (input_msg_s){special, msg_reset_display};
+    break;
+
   // Reinitialize game controllers on controller add/remove/remap
   case SDL_CONTROLLERDEVICEADDED:
   case SDL_CONTROLLERDEVICEREMOVED:
@@ -360,5 +368,16 @@
   // Query for SDL events
   handle_sdl_events();
 
-  return (input_msg_s){key.type, keycode};
+  if (keycode == (key_start|key_select|key_opt|key_edit)){
+    key = (input_msg_s){special,msg_reset_display};
+  }
+
+  if (key.type == normal) {
+    /* Normal input keys go through some event-based manipulation in
+       handle_sdl_events(), the value is stored in keycode variable */
+    return (input_msg_s){key.type, keycode};
+  } else {
+    // Special event keys already have the correct keycode baked in
+    return key;
+  }
 }
\ No newline at end of file
--- a/input.h
+++ b/input.h
@@ -13,7 +13,8 @@
 } input_type_t;
 
 typedef enum special_messages_t {
-  msg_quit
+  msg_quit = 1,
+  msg_reset_display = 2
 } special_messages_t;
 
 typedef struct input_msg_s {
--- a/main.c
+++ b/main.c
@@ -17,6 +17,7 @@
 #define serial_read_size 1024
 
 uint8_t run = 1;
+uint8_t need_display_reset = 0;
 
 // Handles CTRL+C / SIGINT
 void intHandler(int dummy) { run = 0; }
@@ -81,13 +82,21 @@
       }
       break;
     case special:
-      switch (input.value) {
-      case msg_quit:
-        run = 0;
+      if (input.value != prev_input) {
+        prev_input = input.value;
+        switch (input.value) {
+        case msg_quit:
+          run = 0;
+          break;
+        case msg_reset_display:
+          reset_display(port);
+          break;
+        default:
+          break;
+        }
         break;
       }
-      break;
-    }    
+    }
 
     // read serial port
     size_t bytes_read = sp_nonblocking_read(port, serial_buf, serial_read_size);
@@ -102,7 +111,11 @@
         // process the incoming bytes into commands and draw them
         int n = slip_read_byte(&slip, rx);
         if (n != SLIP_NO_ERROR) {
-          SDL_LogError(SDL_LOG_CATEGORY_ERROR, "SLIP error %d\n", n);
+          if (n == SLIP_ERROR_INVALID_PACKET) {
+            reset_display(port);
+          } else {
+            SDL_LogError(SDL_LOG_CATEGORY_ERROR, "SLIP error %d\n", n);
+          }
         }
       }
       usleep(10);
@@ -110,7 +123,6 @@
       render_screen();
       usleep(100);
     }
-    
   }
 
   // exit, clean up
--- a/slip.c
+++ b/slip.c
@@ -77,7 +77,9 @@
   case SLIP_STATE_NORMAL:
     switch (byte) {
     case SLIP_SPECIAL_BYTE_END:
-      slip->descriptor->recv_message(slip->descriptor->buf, slip->size);
+      if (!slip->descriptor->recv_message(slip->descriptor->buf, slip->size)){
+        error = SLIP_ERROR_INVALID_PACKET;
+      }
       reset_rx(slip);
       break;
     case SLIP_SPECIAL_BYTE_ESC:
--- a/slip.h
+++ b/slip.h
@@ -46,14 +46,12 @@
 typedef struct {
         uint8_t *buf;
         uint32_t buf_size;
-        //struct command_queues *command_queues;
-        void (*recv_message)(uint8_t *data, uint32_t size);
+        int (*recv_message)(uint8_t *data, uint32_t size);
 } slip_descriptor_s;
 
 typedef struct {
         slip_state_t state;
         uint32_t size;
-        uint16_t crc;
         const slip_descriptor_s *descriptor;
 } slip_handler_s;
 
@@ -61,6 +59,7 @@
         SLIP_NO_ERROR = 0x00,
         SLIP_ERROR_BUFFER_OVERFLOW,
         SLIP_ERROR_UNKNOWN_ESCAPED_BYTE,
+        SLIP_ERROR_INVALID_PACKET
 } slip_error_t;
 
 slip_error_t slip_init(slip_handler_s *slip, const slip_descriptor_s *descriptor);
--- a/write.c
+++ b/write.c
@@ -7,10 +7,26 @@
 #include <stdio.h>
 #include <unistd.h>
 
-int enable_and_reset_display(struct sp_port *port) {
+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;
@@ -17,17 +33,13 @@
   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;
   }
 
   usleep(500);
-  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);
+  if (!reset_display(port)){
+    return 0;
   }
-  sleep(1);
-
   return 1;
 }
 
--- a/write.h
+++ b/write.h
@@ -7,6 +7,7 @@
 #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);
--