From 3b2c2cf6b2af9e76b343a5a8fc8e9245f240690d Mon Sep 17 00:00:00 2001 From: lonkaars Date: Sun, 29 May 2022 16:27:29 +0200 Subject: serial parsing working on client --- client/errcatch.c | 19 ++++++++++ client/main.c | 30 +++++----------- client/main.h | 12 +++++++ client/makefile | 2 +- client/readme.md | 3 +- client/serial.c | 46 ++++++++++++++++++++++++ client/serial.h | 2 ++ client/serial_linux.c | 2 +- client/setup.c | 29 +++++++++++++++ client/setup.h | 3 ++ client/ui.c | 19 ++++++++++ client/ui.h | 58 ++++++++++++++++++++++++++++++ robot/errcatch.c | 46 ++---------------------- robot/errcatch.h | 34 ------------------ robot/hypervisor.c | 2 +- robot/main.c | 1 + robot/modes.c | 2 +- robot/sercomm.c | 22 +----------- robot/sim.c | 2 +- shared/errcatch.c | 46 ++++++++++++++++++++++++ shared/errcatch.h | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++ shared/errors.h | 64 --------------------------------- shared/serial_parse.c | 21 +++++++++++ 23 files changed, 372 insertions(+), 191 deletions(-) create mode 100644 client/errcatch.c create mode 100644 client/main.h create mode 100644 client/serial.c create mode 100644 client/setup.c create mode 100644 client/setup.h create mode 100644 client/ui.c create mode 100644 client/ui.h delete mode 100644 robot/errcatch.h create mode 100644 shared/errcatch.c create mode 100644 shared/errcatch.h delete mode 100644 shared/errors.h diff --git a/client/errcatch.c b/client/errcatch.c new file mode 100644 index 0000000..e8d696a --- /dev/null +++ b/client/errcatch.c @@ -0,0 +1,19 @@ +#include "../shared/errcatch.h" + +void w2_errcatch_handle_error(w2_s_error *error) { + // TODO: handle more error types + switch (error->code) { + case W2_E_WARN_UNCAUGHT_ERROR: { + break; + } + default: { + g_w2_error_uncaught = true; +#ifdef W2_SIM + simwarn("Uncaught/unhandled error found with code 0x%02x\n", error->code); +#endif + } + } + + return; +} + diff --git a/client/main.c b/client/main.c index d51f30b..1060f7d 100644 --- a/client/main.c +++ b/client/main.c @@ -1,29 +1,15 @@ +#include "setup.h" +#include "../shared/errcatch.h" +#include "main.h" #include "serial.h" - -#include -#include +#include "ui.h" int main(int argc, char **argv) { - if (argc < 2) { - printf("usage: %s \n", argv[0]); - return 1; - } - - if (w2_serial_open(argv[1]) == 0) { - printf("serial port open fout"); - return 1; - } - - printf("writing...\n"); - bool success = w2_serial_write("\xff\x14", 2); - printf("writing %s\n", success ? "succeeded" : "failed"); + w2_client_setup(argc, argv); - printf("reading...\n"); while (1) { - int res = w2_serial_read(); - if (res == -1) continue; - - printf("%02x ", (uint8_t)res); - fflush(stdout); + w2_serial_main(); + w2_errcatch_main(); + w2_ui_main(); } } diff --git a/client/main.h b/client/main.h new file mode 100644 index 0000000..7bb2173 --- /dev/null +++ b/client/main.h @@ -0,0 +1,12 @@ +#pragma once + +#include "../shared/protocol.h" + +typedef struct { + unsigned int ping; + w2_s_cmd_info_tx info; + w2_s_cmd_sens_tx io; +} w2_s_client_state; + +extern w2_s_client_state g_w2_state; + diff --git a/client/makefile b/client/makefile index 87d06a9..f70f70f 100644 --- a/client/makefile +++ b/client/makefile @@ -10,7 +10,7 @@ all: $(EXECNAME) SOURCES := $(wildcard *.c) HEADERS := $(wildcard *.h) -# include ../shared/makefile +include ../shared/makefile OBJECTS := $(patsubst %.c,%.o, $(SOURCES)) diff --git a/client/readme.md b/client/readme.md index 2a8c19f..1fbd49c 100644 --- a/client/readme.md +++ b/client/readme.md @@ -27,7 +27,8 @@ the robot in various ways. it primarily works in a bios-like way, with the user having access to multiple tabs containing options or custom interface elements. to start the interface, the user should run `./main `. the interface -could look something like this (with colored text for element seperation): +could look something like this (with colored text for element seperation, [see +on figma](https://www.figma.com/file/vZ6rQp2G1HBAmbdrkxIZJ3/terminal-app)): ``` verbonden, 2ms ping (0.0.2-11-g92c394b) batterij 100% diff --git a/client/serial.c b/client/serial.c new file mode 100644 index 0000000..6f667a8 --- /dev/null +++ b/client/serial.c @@ -0,0 +1,46 @@ +#include "serial.h" +#include "../shared/protocol.h" +#include "../shared/serial_parse.h" + +void w2_serial_main() { + int temp; + while ((temp = w2_serial_read()) != -1) w2_serial_parse(temp); + w2_serial_write("\xff\x14", 2); +} + +void w2_cmd_ping_tx(w2_s_bin *data) { + printf("w2_cmd_ping_tx()\n"); +} +void w2_cmd_expt_tx(w2_s_bin *data) { + printf("w2_cmd_expt_tx()\n"); +} +void w2_cmd_mode_tx(w2_s_bin *data) { + printf("w2_cmd_mode_tx()\n"); +} +void w2_cmd_cord_tx(w2_s_bin *data) { + printf("w2_cmd_cord_tx()\n"); +} +void w2_cmd_bomd_tx(w2_s_bin *data) { + printf("w2_cmd_bomd_tx()\n"); +} +void w2_cmd_sens_tx(w2_s_bin *data) { + printf("w2_cmd_sens_tx()\n"); +} +void w2_cmd_info_tx(w2_s_bin *data) { + printf("w2_cmd_info_tx()\n"); +} + +void w2_cmd_ping_rx(w2_s_bin *data) { return; } +void w2_cmd_mode_rx(w2_s_bin *data) { return; } +void w2_cmd_sped_rx(w2_s_bin *data) { return; } +void w2_cmd_dirc_rx(w2_s_bin *data) { return; } +void w2_cmd_cord_rx(w2_s_bin *data) { return; } +void w2_cmd_bomd_rx(w2_s_bin *data) { return; } +void w2_cmd_sres_rx(w2_s_bin *data) { return; } +void w2_cmd_mcfg_rx(w2_s_bin *data) { return; } +void w2_cmd_sens_rx(w2_s_bin *data) { return; } +void w2_cmd_info_rx(w2_s_bin *data) { return; } +void w2_cmd_disp_rx(w2_s_bin *data) { return; } +void w2_cmd_play_rx(w2_s_bin *data) { return; } +void w2_cmd_cled_rx(w2_s_bin *data) { return; } + diff --git a/client/serial.h b/client/serial.h index caa3cda..b29dfb5 100644 --- a/client/serial.h +++ b/client/serial.h @@ -16,3 +16,5 @@ bool w2_serial_write(char *data, uint8_t length); bool w2_serial_open(const char *port_name); /** close serial port */ void w2_serial_close(); + +void w2_serial_main(); diff --git a/client/serial_linux.c b/client/serial_linux.c index 080dca1..2497fac 100644 --- a/client/serial_linux.c +++ b/client/serial_linux.c @@ -63,7 +63,7 @@ speed_t w2_baud_map(int baud) { int w2_serial_read() { int return_val; int bytes = read(g_w2_serial_handle, &return_val, 1); - return return_val == -1 || bytes != 1 ? -1 : (uint8_t)return_val; + return bytes != 1 ? -1 : (uint8_t)return_val; } bool w2_serial_write(char *data, uint8_t length) { diff --git a/client/setup.c b/client/setup.c new file mode 100644 index 0000000..d7314e8 --- /dev/null +++ b/client/setup.c @@ -0,0 +1,29 @@ +#include +#include + +#include "serial.h" +#include "setup.h" +#include "../shared/bin.h" +#include "../shared/protocol.h" + +// pointers for endianness check +static const uint16_t _test = 1; +static const uint8_t *_ptest = (uint8_t *)&_test; +uint8_t g_w2_endianness; + +void w2_client_setup(int argc, char** argv) { + if (argc < 2) { + printf("usage: %s \n", argv[0]); + exit(1); + } + + if (w2_serial_open(argv[1]) == 0) { + printf("serial port open fout\n"); + exit(1); + } + + w2_cmd_setup_handlers(); + + // check endianness + g_w2_endianness = *_ptest; +} diff --git a/client/setup.h b/client/setup.h new file mode 100644 index 0000000..4b4a040 --- /dev/null +++ b/client/setup.h @@ -0,0 +1,3 @@ +#pragma once + +void w2_client_setup(int argc, char** argv); diff --git a/client/ui.c b/client/ui.c new file mode 100644 index 0000000..4a8e64d --- /dev/null +++ b/client/ui.c @@ -0,0 +1,19 @@ +#include "ui.h" + +void w2_ui_main() { + w2_ui_update(); + w2_ui_paint(); +} + +void w2_ui_update() { + // measure terminal width and height +} + +void w2_ui_paint() { + + w2_ui_paint_statusbar(); +} + +void w2_ui_paint_statusbar() { + +} diff --git a/client/ui.h b/client/ui.h new file mode 100644 index 0000000..433d610 --- /dev/null +++ b/client/ui.h @@ -0,0 +1,58 @@ +#pragma once + +#include + +#include "../shared/bool.h" + +typedef struct { + unsigned int width; + unsigned int height; + unsigned int cursor_pos; +} w2_s_ui_tty_canvas; + +typedef enum { + W2_UI_COL_BLK, + W2_UI_COL_RED, + W2_UI_COL_GRN, + W2_UI_COL_YEL, + W2_UI_COL_BLU, + W2_UI_COL_MAG, + W2_UI_COL_CYN, + W2_UI_COL_WHT, + W2_UI_COL_RST, +} w2_e_colors; + +typedef enum { + W2_UI_ALIGN_LEFT, + W2_UI_ALIGN_CENTER, + W2_UI_ALIGN_RIGHT, +} w2_e_alignment; + +extern bool g_w2_ui_enable_color; +extern w2_s_ui_tty_canvas g_w2_ui_canvas; + +/** update terminal props */ +void w2_ui_update(); +/** clear screen */ +void w2_ui_clear(); +/** draw complete ui */ +void w2_ui_paint(); +/** draw status bar */ +void w2_ui_paint_statusbar(); +/** update and paint */ +void w2_ui_main(); + +/** echo ansi color code for foreground color */ +void w2_ui_set_fg(w2_e_colors color); +/** echo ansi color code for background color */ +void w2_ui_set_bg(w2_e_colors color); + +/** align `text` `align` with `text` buffer length `length` */ +void w2_ui_align(char* text, w2_e_alignment align, unsigned int length); + +/** + * trim spaces from `top` and overlay on top of `bottom` + * both strings should be at least `length` long + */ +void w2_ui_overlay(char* bottom, char* top, unsigned int length); + diff --git a/robot/errcatch.c b/robot/errcatch.c index 8df90b8..0f809f9 100644 --- a/robot/errcatch.c +++ b/robot/errcatch.c @@ -1,52 +1,10 @@ -#include #include -#include "errcatch.h" +#include "../shared/errcatch.h" #include "modes.h" #include "orangutan_shim.h" #include "sercomm.h" -w2_s_error *g_w2_error_buffer[W2_ERROR_BUFFER_SIZE] = {}; -uint8_t g_w2_error_index = 0; -uint8_t g_w2_error_offset = 0; -uint8_t g_w2_error_buffer_full = 0; -uint8_t g_w2_error_uncaught = 0; - -void w2_errcatch_main() { - while (g_w2_error_offset != g_w2_error_index) { - w2_s_error *error = g_w2_error_buffer[g_w2_error_offset]; - w2_errcatch_handle_error(error); - g_w2_error_offset = (g_w2_error_offset + 1) % W2_ERROR_BUFFER_SIZE; - } - if (g_w2_error_buffer_full) { - w2_errcatch_throw(W2_E_WARN_ERR_BUFFER_FULL); - g_w2_error_buffer_full = 0; - } - if (g_w2_error_uncaught) { - w2_errcatch_throw(W2_E_WARN_UNCAUGHT_ERROR); - g_w2_error_uncaught = 0; - } -} - -w2_s_error *w2_alloc_error(w2_e_errorcode code, uint16_t length, const char *message) { - w2_s_error *error = malloc(sizeof(w2_s_error) + length); - memcpy(error, &(w2_s_error const){.code = code, .message_length = length}, sizeof(w2_s_error)); - strncpy(error->message, message, length); - - return error; -} - -void w2_errcatch_throw(w2_e_errorcode code) { w2_errcatch_throw_msg(code, 0, ""); } -void w2_errcatch_throw_msg(w2_e_errorcode code, uint16_t length, const char *message) { - uint8_t next_index = (g_w2_error_index + 1) % W2_ERROR_BUFFER_SIZE; - g_w2_error_buffer_full = next_index == g_w2_error_offset; - free(g_w2_error_buffer[g_w2_error_index]); - w2_s_error *error = w2_alloc_error(code, length, message); - g_w2_error_buffer[g_w2_error_index] = error; - if (g_w2_error_buffer_full) return; - g_w2_error_index = next_index; -} - void w2_errcatch_handle_error(w2_s_error *error) { uint8_t severity = error->code & W2_E_TYPE_MASK; @@ -59,7 +17,7 @@ void w2_errcatch_handle_error(w2_s_error *error) { break; } default: { - g_w2_error_uncaught = 1; + g_w2_error_uncaught = true; #ifdef W2_SIM simwarn("Uncaught/unhandled error found with code 0x%02x\n", error->code); #endif diff --git a/robot/errcatch.h b/robot/errcatch.h deleted file mode 100644 index add4ece..0000000 --- a/robot/errcatch.h +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once - -/** @file errcatch.h */ - -#include - -#include "../shared/consts.h" -#include "../shared/errors.h" - -/** error ring buffer */ -extern w2_s_error *g_w2_error_buffer[W2_ERROR_BUFFER_SIZE]; -/** stores head of ring buffer */ -extern uint8_t g_w2_error_index; -/** stores start of ring buffer */ -extern uint8_t g_w2_error_offset; - -/** error-handler module main */ -void w2_errcatch_main(); - -/** handle error */ -void w2_errcatch_handle_error(w2_s_error *error); - -/** append error to error buffer */ -void w2_errcatch_throw(w2_e_errorcode code); - -/** append error to error buffer (with debug message) */ -void w2_errcatch_throw_msg(w2_e_errorcode code, uint16_t length, const char *message); - -/** - * allocate and initialize error struct - * - * TODO: doesn't handle null pointers from malloc - */ -w2_s_error *w2_alloc_error(w2_e_errorcode code, uint16_t length, const char *message); diff --git a/robot/hypervisor.c b/robot/hypervisor.c index 1fd3ac2..e781877 100644 --- a/robot/hypervisor.c +++ b/robot/hypervisor.c @@ -1,6 +1,6 @@ #include "hypervisor.h" #include "../shared/util.h" -#include "errcatch.h" +#include "../shared/errcatch.h" #include "io.h" #include "modes.h" #include "orangutan_shim.h" diff --git a/robot/main.c b/robot/main.c index d76dbaf..eba94cb 100644 --- a/robot/main.c +++ b/robot/main.c @@ -5,6 +5,7 @@ #include "sim.h" #endif +#include int main(int argc, char **argv) { #ifdef W2_SIM w2_sim_setup(argc, argv); diff --git a/robot/modes.c b/robot/modes.c index 9877f6e..55bb1d4 100644 --- a/robot/modes.c +++ b/robot/modes.c @@ -1,7 +1,7 @@ #include "modes.h" #include "../shared/protocol.h" #include "../shared/util.h" -#include "errcatch.h" +#include "../shared/errcatch.h" #include "sercomm.h" /** function pointer to current mode */ diff --git a/robot/sercomm.c b/robot/sercomm.c index 07c4bd8..e346cc2 100644 --- a/robot/sercomm.c +++ b/robot/sercomm.c @@ -3,7 +3,7 @@ #include "../shared/bin.h" #include "../shared/serial_parse.h" -#include "errcatch.h" +#include "../shared/errcatch.h" #include "hypervisor.h" #include "io.h" #include "mode_dirc.h" @@ -58,26 +58,6 @@ void w2_sercomm_append_msg(w2_s_bin *data) { g_w2_sercomm_index = next_index; } -void w2_cmd_handler(uint8_t data[W2_SERIAL_READ_BUFFER_SIZE], uint8_t data_length) { - w2_s_bin *copy = w2_bin_s_alloc(data_length, data); - void (*handler)(w2_s_bin *) = g_w2_cmd_handlers[data[0]]; - - if (handler == NULL) { -#ifdef W2_SIM - // TODO throw warning - simwarn("unknown serial message with code 0x%02x\n", data[0]); -#endif - w2_errcatch_throw(W2_E_WARN_SERIAL_NOISY); - } else { -#ifdef W2_SIM - w2_sim_print_serial(copy); -#endif - handler(copy); - } - - free(copy); -} - void w2_cmd_ping_rx(w2_s_bin *data) { w2_s_cmd_ping_rx *message = malloc(w2_cmd_sizeof(data->data, data->bytes)); memcpy(message, data->data, data->bytes); diff --git a/robot/sim.c b/robot/sim.c index 34e4932..0e4c9b7 100644 --- a/robot/sim.c +++ b/robot/sim.c @@ -10,7 +10,7 @@ #include "../shared/consts.h" #include "../shared/protocol.h" #include "sercomm.h" -#include "errcatch.h" +#include "../shared/errcatch.h" struct timespec reference_time; // NOLINT bool g_w2_sim_headless = false; diff --git a/shared/errcatch.c b/shared/errcatch.c new file mode 100644 index 0000000..ff7fc93 --- /dev/null +++ b/shared/errcatch.c @@ -0,0 +1,46 @@ +#include +#include + +#include "errcatch.h" + +w2_s_error *g_w2_error_buffer[W2_ERROR_BUFFER_SIZE] = {}; +uint8_t g_w2_error_index = 0; +uint8_t g_w2_error_offset = 0; +bool g_w2_error_buffer_full = 0; +bool g_w2_error_uncaught = 0; + +void w2_errcatch_main() { + while (g_w2_error_offset != g_w2_error_index) { + w2_s_error *error = g_w2_error_buffer[g_w2_error_offset]; + w2_errcatch_handle_error(error); + g_w2_error_offset = (g_w2_error_offset + 1) % W2_ERROR_BUFFER_SIZE; + } + if (g_w2_error_buffer_full) { + w2_errcatch_throw(W2_E_WARN_ERR_BUFFER_FULL); + g_w2_error_buffer_full = 0; + } + if (g_w2_error_uncaught) { + w2_errcatch_throw(W2_E_WARN_UNCAUGHT_ERROR); + g_w2_error_uncaught = 0; + } +} + +w2_s_error *w2_alloc_error(w2_e_errorcode code, uint16_t length, const char *message) { + w2_s_error *error = malloc(sizeof(w2_s_error) + length); + memcpy(error, &(w2_s_error const){.code = code, .message_length = length}, sizeof(w2_s_error)); + strncpy(error->message, message, length); + + return error; +} + +void w2_errcatch_throw(w2_e_errorcode code) { w2_errcatch_throw_msg(code, 0, ""); } +void w2_errcatch_throw_msg(w2_e_errorcode code, uint16_t length, const char *message) { + uint8_t next_index = (g_w2_error_index + 1) % W2_ERROR_BUFFER_SIZE; + g_w2_error_buffer_full = next_index == g_w2_error_offset; + free(g_w2_error_buffer[g_w2_error_index]); + w2_s_error *error = w2_alloc_error(code, length, message); + g_w2_error_buffer[g_w2_error_index] = error; + if (g_w2_error_buffer_full) return; + g_w2_error_index = next_index; +} + diff --git a/shared/errcatch.h b/shared/errcatch.h new file mode 100644 index 0000000..9b14cc2 --- /dev/null +++ b/shared/errcatch.h @@ -0,0 +1,98 @@ +#pragma once + +/** @file errcatch.h */ + +#include + +#include "consts.h" +#include "bool.h" + +#define W2_E_TYPE_MASK (0b11 << 6) + +#define W2_E_TYPE_CRIT (0b00 << 6) +#define W2_E_TYPE_WARN (0b01 << 6) +#define W2_E_TYPE_INFO (0b10 << 6) +#define W2_E_TYPE_VERB (0b11 << 6) + +/** + * enum storing all error codes + * + * error codes are between 0-63 because the two most significant bits are + * reserved for error type checking + */ +typedef enum { + /** wireless connection lost from either robot or client-side */ + W2_E_CRIT_CONN_LOST = 0x00 | W2_E_TYPE_CRIT, + /** serial COM-port unavalable. client-side only */ + W2_E_CRIT_COM_UNAVAILABLE = 0x01 | W2_E_TYPE_CRIT, + /** line unable to be found automatically */ + W2_E_CRIT_LINE_LOST = 0x02 | W2_E_TYPE_CRIT, + /** obstacle unavoidable, robot stuck */ + W2_E_CRIT_OBSTACLE_STUCK = 0x03 | W2_E_TYPE_CRIT, + /** semver major version doesn't match */ + W2_E_CRIT_VERSION_INCOMPATIBLE = 0x04 | W2_E_TYPE_CRIT, + + /** battery low, returning to charging station */ + W2_E_WARN_BATTERY_LOW = 0x00 | W2_E_TYPE_WARN, + /** obstacle detected, waiting then trying other route */ + W2_E_WARN_OBSTACLE_DETECTED = 0x01 | W2_E_TYPE_WARN, + /** logic cycle took longer than `W2_MAX_MODULE_CYCLE_MS` */ + W2_E_WARN_CYCLE_EXPIRED = 0x02 | W2_E_TYPE_WARN, + /** error thrown without handler, gets thrown on next cycle */ + W2_E_WARN_UNCAUGHT_ERROR = 0x03 | W2_E_TYPE_WARN, + /** error buffer full, gets thrown on next cycle */ + W2_E_WARN_ERR_BUFFER_FULL = 0x04 | W2_E_TYPE_WARN, + /** line lost, trying to calibrate */ + W2_E_WARN_LINE_LOST = 0x05 | W2_E_TYPE_WARN, + /** serial buffer full, gets thrown on next cycle */ + W2_E_WARN_SERCOMM_BUFFER_FULL = 0x06 | W2_E_TYPE_WARN, + /** semver minor version doesn't match */ + W2_E_WARN_VERSION_INCOMPATIBLE = 0x07 | W2_E_TYPE_WARN, + /** unknown message encountered (noisy channel?) */ + W2_E_WARN_SERIAL_NOISY = 0x09 | W2_E_TYPE_WARN, + /** mode history index out of bounds */ + W2_E_WARN_MODE_HISTORY_BUFFER_IOB = 0x0a | W2_E_TYPE_WARN, +} w2_e_errorcode; + +/** + * error struct + * + * holds an error with type `code`, and an optional `message` with length + * `message_length` + */ +typedef struct { + w2_e_errorcode code; + uint8_t message_length; + char message[]; +} w2_s_error; + +/** error ring buffer */ +extern w2_s_error *g_w2_error_buffer[W2_ERROR_BUFFER_SIZE]; +/** stores head of ring buffer */ +extern uint8_t g_w2_error_index; +/** stores start of ring buffer */ +extern uint8_t g_w2_error_offset; +/** error buffer full flag */ +extern bool g_w2_error_buffer_full; +/** uncaught error flag */ +extern bool g_w2_error_uncaught; + +/** error-handler module main */ +void w2_errcatch_main(); + +/** handle error */ +void w2_errcatch_handle_error(w2_s_error *error); + +/** append error to error buffer */ +void w2_errcatch_throw(w2_e_errorcode code); + +/** append error to error buffer (with debug message) */ +void w2_errcatch_throw_msg(w2_e_errorcode code, uint16_t length, const char *message); + +/** + * allocate and initialize error struct + * + * TODO: doesn't handle null pointers from malloc + */ +w2_s_error *w2_alloc_error(w2_e_errorcode code, uint16_t length, const char *message); + diff --git a/shared/errors.h b/shared/errors.h deleted file mode 100644 index 344a506..0000000 --- a/shared/errors.h +++ /dev/null @@ -1,64 +0,0 @@ -#pragma once - -/** @file errors.h */ - -#include - -#define W2_E_TYPE_MASK (0b11 << 6) - -#define W2_E_TYPE_CRIT (0b00 << 6) -#define W2_E_TYPE_WARN (0b01 << 6) -#define W2_E_TYPE_INFO (0b10 << 6) -#define W2_E_TYPE_VERB (0b11 << 6) - -/** - * enum storing all error codes - * - * error codes are between 0-63 because the two most significant bits are - * reserved for error type checking - */ -typedef enum { - /** wireless connection lost from either robot or client-side */ - W2_E_CRIT_CONN_LOST = 0x00 | W2_E_TYPE_CRIT, - /** serial COM-port unavalable. client-side only */ - W2_E_CRIT_COM_UNAVAILABLE = 0x01 | W2_E_TYPE_CRIT, - /** line unable to be found automatically */ - W2_E_CRIT_LINE_LOST = 0x02 | W2_E_TYPE_CRIT, - /** obstacle unavoidable, robot stuck */ - W2_E_CRIT_OBSTACLE_STUCK = 0x03 | W2_E_TYPE_CRIT, - /** semver major version doesn't match */ - W2_E_CRIT_VERSION_INCOMPATIBLE = 0x04 | W2_E_TYPE_CRIT, - - /** battery low, returning to charging station */ - W2_E_WARN_BATTERY_LOW = 0x00 | W2_E_TYPE_WARN, - /** obstacle detected, waiting then trying other route */ - W2_E_WARN_OBSTACLE_DETECTED = 0x01 | W2_E_TYPE_WARN, - /** logic cycle took longer than `W2_MAX_MODULE_CYCLE_MS` */ - W2_E_WARN_CYCLE_EXPIRED = 0x02 | W2_E_TYPE_WARN, - /** error thrown without handler, gets thrown on next cycle */ - W2_E_WARN_UNCAUGHT_ERROR = 0x03 | W2_E_TYPE_WARN, - /** error buffer full, gets thrown on next cycle */ - W2_E_WARN_ERR_BUFFER_FULL = 0x04 | W2_E_TYPE_WARN, - /** line lost, trying to calibrate */ - W2_E_WARN_LINE_LOST = 0x05 | W2_E_TYPE_WARN, - /** serial buffer full, gets thrown on next cycle */ - W2_E_WARN_SERCOMM_BUFFER_FULL = 0x06 | W2_E_TYPE_WARN, - /** semver minor version doesn't match */ - W2_E_WARN_VERSION_INCOMPATIBLE = 0x07 | W2_E_TYPE_WARN, - /** unknown message encountered (noisy channel?) */ - W2_E_WARN_SERIAL_NOISY = 0x09 | W2_E_TYPE_WARN, - /** mode history index out of bounds */ - W2_E_WARN_MODE_HISTORY_BUFFER_IOB = 0x0a | W2_E_TYPE_WARN, -} w2_e_errorcode; - -/** - * error struct - * - * holds an error with type `code`, and an optional `message` with length - * `message_length` - */ -typedef struct { - w2_e_errorcode code; - uint8_t message_length; - char message[]; -} w2_s_error; diff --git a/shared/serial_parse.c b/shared/serial_parse.c index b1b4f50..49f4cbf 100644 --- a/shared/serial_parse.c +++ b/shared/serial_parse.c @@ -2,6 +2,10 @@ #include "consts.h" #include "serial_parse.h" +#include "errcatch.h" +#ifdef W2_SIM +#include "../robot/orangutan_shim.h" +#endif bool w2_serial_parse(uint8_t byte) { static uint8_t current_message[W2_SERIAL_READ_BUFFER_SIZE] = {0}; @@ -38,3 +42,20 @@ bool w2_serial_parse(uint8_t byte) { return W2_SERIAL_READ_SUCCESS; } + +void w2_cmd_handler(uint8_t data[W2_SERIAL_READ_BUFFER_SIZE], uint8_t data_length) { + w2_s_bin *copy = w2_bin_s_alloc(data_length, data); + void (*handler)(w2_s_bin *) = g_w2_cmd_handlers[data[0]]; + + if (handler == NULL) { + w2_errcatch_throw(W2_E_WARN_SERIAL_NOISY); + } else { +#ifdef W2_SIM + w2_sim_print_serial(copy); +#endif + handler(copy); + } + + free(copy); +} + -- cgit v1.2.3