blob: 3210b277b740613dd86541de21f931315361b222 [file] [log] [blame]
Harald Welteff9f4ce2019-02-24 22:51:09 +01001#include <string.h>
2#include <stdint.h>
3#include <stdio.h>
4
5#include <utils.h>
6
7#include "atmel_start.h"
8#include "command.h"
9
10struct cmd_state {
11 const char *prompt;
12 char buf[128];
13 unsigned int buf_idx;
14 const struct command_fn *cmd[32];
15 unsigned int cmd_idx;
16};
17
18static struct cmd_state g_cmds;
19
20int command_register(const struct command_fn *cmd)
21{
22 if (g_cmds.cmd_idx >= ARRAY_SIZE(g_cmds.cmd))
23 return -1;
24 g_cmds.cmd[g_cmds.cmd_idx++] = cmd;
25 return 0;
26}
27
28DEFUN(help, help_cmd, "help", "Print command reference")
29{
30 unsigned int i;
31 printf("Help:\r\n");
32 printf(" Command Help\r\n");
33 printf(" ---------------- ----\r\n");
34 for (i = 0; i < g_cmds.cmd_idx; i++)
35 printf(" %-16s %s\r\n", g_cmds.cmd[i]->command, g_cmds.cmd[i]->help);
36}
37
38static void cmd_execute()
39{
40 char *argv[16];
41 unsigned int i;
42 int argc = 0;
43 char *cur;
44
45 printf("\r\n");
46 memset(argv, 0, sizeof(argv));
47
48 for (cur = strtok(g_cmds.buf, " "); cur; cur = strtok(NULL, " ")) {
49 if (argc >= ARRAY_SIZE(argv))
50 break;
51 argv[argc++] = cur;
52 }
53
54 for (i = 0; i < g_cmds.cmd_idx; i++) {
55 if (!strcmp(g_cmds.cmd[i]->command, argv[0])) {
56 g_cmds.cmd[i]->fn(argc, argv);
57 return;
58 }
59 }
60 printf("Unknown command: '%s'\r\n", argv[0]);
61}
62
63static void cmd_buf_reset(void)
64{
65 memset(g_cmds.buf, 0, sizeof(g_cmds.buf));
66 g_cmds.buf_idx = 0;
67}
68
69static void cmd_buf_append(char c)
70{
71 g_cmds.buf[g_cmds.buf_idx++] = c;
72}
73
Harald Weltee7aa5342019-04-16 21:11:14 +020074void command_print_prompt(void)
75{
76 printf(g_cmds.prompt);
77}
78
Harald Welteff9f4ce2019-02-24 22:51:09 +010079void command_try_recv(void)
80{
81 unsigned int i = 0;
82
83 /* yield CPU after maximum of 10 received characters */
84 while (usart_sync_is_rx_not_empty(&UART_debug) && (i < 10)) {
85 int c = getchar();
86 if (c < 0)
87 return;
88 putchar(c);
89 if (c == '\r' || c == '\n' || g_cmds.buf_idx >= sizeof(g_cmds.buf)-1) {
90 cmd_execute();
91 cmd_buf_reset();
92 printf(g_cmds.prompt);
93 return;
94 }
95 /* append character */
96 cmd_buf_append(c);
97
98 i++;
99 }
100}
101
102void command_init(const char *prompt)
103{
104 g_cmds.prompt = prompt;
105 command_register(&help_cmd);
106}