summaryrefslogtreecommitdiff
path: root/src/cmd.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd.c')
-rw-r--r--src/cmd.c86
1 files changed, 86 insertions, 0 deletions
diff --git a/src/cmd.c b/src/cmd.c
new file mode 100644
index 0000000..43b9bfc
--- /dev/null
+++ b/src/cmd.c
@@ -0,0 +1,86 @@
+/*
+ * src/cmd.c
+ * (c) 2021 Jonas Gunz <himself@jonasgunz.de>
+ * License: All rights reserved.
+ */
+
+#include "cmd.h"
+
+struct {
+ uint8_t state;
+ uint8_t cmd;
+ uint8_t argv[_CMD_MAX_ARGC];
+} cmd_state;
+
+const struct {
+ char literal;
+ void (*fkt)(uint8_t[]);
+ uint8_t argc;
+} cmd[_CMD_CNT] = {
+ {0,cmd_err,0},
+ {'p',cmd_set_pwm,2}
+};
+
+void cmd_init() {
+ cmd_state.state = 0;
+ cmd_state.cmd = 0;
+}
+
+void cmd_tick(char _c) {
+ uint8_t i;
+
+ if(_c == '\r') {
+ /* if cmd is not cmd_err and argc do not match */
+ if( cmd_state.cmd && cmd[cmd_state.cmd].argc != cmd_state.state - 1 ) {
+ /* set cmd_err to _ERR_ARGC */
+ cmd_state.cmd = 0;
+ cmd_state.argv[0] = _ERR_ARGC;
+ }
+
+ (*cmd[cmd_state.cmd].fkt)(cmd_state.argv);
+ cmd_state.state = 0;
+ cmd_state.cmd = 0;
+ return;
+ }
+
+ if(!cmd_state.state) {
+ cmd_state.state = 1;
+ for( i=0; i<_CMD_CNT; i++ ) {
+ if( _c != cmd[i].literal )
+ continue;
+
+ cmd_state.cmd = i;
+ return;
+ }
+
+ cmd_state.cmd = 0;
+ cmd_state.argv[0] = _ERR_CMD;
+ }
+
+ /* Check, if maximum argc is reached */
+ if (cmd_state.state >= _CMD_MAX_ARGC) {
+ cmd_state.cmd = 0;
+ cmd_state.argv[0] = _ERR_ARGC;
+ }
+
+ cmd_state.argv[ (cmd_state.state++) - 1 ] = _c;
+}
+
+void cmd_set_pwm(uint8_t _argv[]) {
+ uart_putchar(_argv[0]);
+ uart_putchar(_argv[1]);
+}
+
+void cmd_err( uint8_t _argv[] ) {
+ switch(_argv[0]) {
+ case _ERR_ARGC:
+ uart_putstring("E:ARG\r\n");
+ break;
+ case _ERR_CMD:
+ uart_putstring("E:CMD\r\n");
+ break;
+ default:
+ uart_putstring("E\r\n");
+
+ }
+}