diff options
| -rw-r--r-- | client/errcatch.c | 19 | ||||
| -rw-r--r-- | client/main.c | 30 | ||||
| -rw-r--r-- | client/main.h | 12 | ||||
| -rw-r--r-- | client/makefile | 2 | ||||
| -rw-r--r-- | client/readme.md | 3 | ||||
| -rw-r--r-- | client/serial.c | 46 | ||||
| -rw-r--r-- | client/serial.h | 2 | ||||
| -rw-r--r-- | client/serial_linux.c | 2 | ||||
| -rw-r--r-- | client/setup.c | 29 | ||||
| -rw-r--r-- | client/setup.h | 3 | ||||
| -rw-r--r-- | client/ui.c | 19 | ||||
| -rw-r--r-- | client/ui.h | 58 | ||||
| -rw-r--r-- | robot/errcatch.c | 46 | ||||
| -rw-r--r-- | robot/errcatch.h | 34 | ||||
| -rw-r--r-- | robot/hypervisor.c | 2 | ||||
| -rw-r--r-- | robot/main.c | 1 | ||||
| -rw-r--r-- | robot/modes.c | 2 | ||||
| -rw-r--r-- | robot/sercomm.c | 22 | ||||
| -rw-r--r-- | robot/sim.c | 2 | ||||
| -rw-r--r-- | shared/errcatch.c | 46 | ||||
| -rw-r--r-- | shared/errcatch.h (renamed from shared/errors.h) | 36 | ||||
| -rw-r--r-- | shared/serial_parse.c | 21 | 
22 files changed, 309 insertions, 128 deletions
| 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 <stdio.h> -#include <unistd.h> +#include "ui.h"  int main(int argc, char **argv) { -	if (argc < 2) { -		printf("usage: %s <serial port>\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 <com-port>`. 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 <stdio.h> +#include <stdlib.h> + +#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 <serial port>\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 <stdint.h> + +#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 <stdlib.h>  #include <string.h> -#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 <stdint.h> - -#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 <unistd.h>  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 <stdlib.h> +#include <string.h> + +#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/errors.h b/shared/errcatch.h index 344a506..9b14cc2 100644 --- a/shared/errors.h +++ b/shared/errcatch.h @@ -1,9 +1,12 @@  #pragma once -/** @file errors.h */ +/** @file errcatch.h */  #include <stdint.h> +#include "consts.h" +#include "bool.h" +  #define W2_E_TYPE_MASK (0b11 << 6)  #define W2_E_TYPE_CRIT (0b00 << 6) @@ -62,3 +65,34 @@ typedef struct {  	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/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); +} + |