summaryrefslogtreecommitdiff
path: root/src/cmd.c
blob: 83451aa81f89035e5d6423f075440aee21dfcbef (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/*
 * src/cmd.c
 * (c) 2021 Jonas Gunz <himself@jonasgunz.de>
 * License: MIT
 */

#include "cmd.h"
#include "helpers.h"
#include <stdint.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,3},
	{'f',cmd_fade_pwm,3}
};

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;
		cmd_state.argv[0] = 0;
		return;
	}

	if(_c == '\n')
		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;

		/* TODO this fixes reset on keysmashing. why? */
		return;
	}

	cmd_state.argv[ (cmd_state.state++) - 1 ] = _c;
}

void cmd_set_pwm(uint8_t _argv[]) {
	uint8_t duty = hex_to_byte((char*)&(_argv[1]));
	uint8_t pin = _argv[0] - 48;

	pwm_set_pin(pin, duty);
}

void cmd_fade_pwm(uint8_t _argv[]) {
	uint8_t duty = hex_to_byte((char*)&(_argv[1]));
	uint8_t pin = _argv[0] - 48;

	pwm_fade_pin(pin, duty);
}

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");

	}
}