blob: 454cd2f581ce86dd20bd8756640c9ad2e2817297 [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 */
Kévin Redon0c3533f2019-04-03 21:00:09 +020084 while (usart_async_rings_is_rx_not_empty(&UART_debug) && (i < 10)) {
Harald Welteff9f4ce2019-02-24 22:51:09 +010085 int c = getchar();
86 if (c < 0)
87 return;
Harald Welteff9f4ce2019-02-24 22:51:09 +010088 if (c == '\r' || c == '\n' || g_cmds.buf_idx >= sizeof(g_cmds.buf)-1) {
Harald Welte34fabac2019-04-17 11:57:07 +020089 /* skip empty commands */
90 if (g_cmds.buf_idx == 0)
91 return;
Harald Welteff9f4ce2019-02-24 22:51:09 +010092 cmd_execute();
93 cmd_buf_reset();
94 printf(g_cmds.prompt);
95 return;
Harald Welte34fabac2019-04-17 11:57:07 +020096 } else {
97 /* print + append character */
98 putchar(c);
99 cmd_buf_append(c);
Harald Welteff9f4ce2019-02-24 22:51:09 +0100100 }
Harald Welteff9f4ce2019-02-24 22:51:09 +0100101
102 i++;
103 }
104}
105
106void command_init(const char *prompt)
107{
108 g_cmds.prompt = prompt;
109 command_register(&help_cmd);
110}