23#include "hardware/gpio.h"
24#include "hardware/structs/io_bank0.h"
25#include "hardware/watchdog.h"
26#include "wizchip_conf.h"
27#include "wizchip_qspi_pio.h"
38#define MAX_CMD_BUFFER_LEN 16
39#define MAX_PIN_NAME_LEN 16
40#define MAX_ARG_BUFFER_LEN 64
75static void cmd_help(
const char* args);
77static void cmd_mem(
const char* args);
78static void cmd_net(
const char* args);
79static void cmd_set(
const char* args);
80static void cmd_get(
const char* args);
82static void cmd_save(
const char* args);
83static void cmd_wipe(
const char* args);
112 {
"help",
cmd_help,
"Show available commands"},
113 {
"status",
cmd_status,
"Show system status and RXC estimate"},
114 {
"mem",
cmd_mem,
"Show RAM/flash memory usage"},
115 {
"save",
cmd_save,
"Persist current configuration to flash"},
116 {
"wipe",
cmd_wipe,
"Erase persistent configuration from flash"},
117 {
"net",
cmd_net,
"Show current network status (W5500)"},
118 {
"set",
cmd_set,
"Set values (e.g. set gpio <pin> <0|1>, set net ip.local <addr>/<cidr>)"},
119 {
"get",
cmd_get,
"Get values (e.g. get gpio <pin>, get net ip.local)"},
120 {
"pininfo",
cmd_pininfo,
"Show pin details: pininfo <pin>"},
137#define INVERT_HELP "Invert pins (comma-separated, e.g. set v24 invert txd,rxd)"
142 "<0|1> Internal or external tx clock"}};
144#define NUM_COMMANDS (sizeof(commands) / sizeof(commands[0]))
145#define NUM_CATEGORIES ARRAY_LEN(categories)
146#define NUM_NET_SUBCMDS ARRAY_LEN(net_subcmds)
147#define NUM_V24_SUBCMDS ARRAY_LEN(v24_subcmds)
148#define NUM_PINS get_num_pins()
154#define NUM_V24_BAUDRATES ARRAY_LEN(v24_baudrates)
166#define NUM_LOGLEVELS ARRAY_LEN(loglevels)
175 .data_len =
sizeof(event_data),
178 memcpy(event.data.bytes, &event_data,
sizeof(event_data));
188 .data_len =
sizeof(get_request),
191 memcpy(event.data.bytes, &get_request,
sizeof(get_request));
199 LOG_PLAIN(
"usage: set v24 polarities txd,rxd,rts\r\n");
218 .data_len =
sizeof(event_data),
221 memcpy(event.data.bytes, &event_data,
sizeof(event_data));
229 LOG_PLAIN(
"usage: set v24 txclock <0|1> \r\n");
237 .data_len =
sizeof(event_data),
240 memcpy(event.data.bytes, &event_data,
sizeof(event_data));
249 LOG_PLAIN(
"usage: set v24 baudrate 9600\r\n");
268 LOG_DEBUG(
"set v24: args='%s'\r\n", args);
269 if (args == NULL || args[0] ==
'\0')
271 LOG_PLAIN(
"usage: set v24 <subcmd> <args>\r\n");
282 if (strncmp(args,
v24_subcmds[i].name, len) == 0 && (args[len] ==
' ' || args[len] ==
'\0'))
284 const char* sub_args = args[len] ==
' ' ? args + len + 1 :
"";
289 LOG_PLAIN(
"unknown v24 subcmd: '%s'\r\n", args);
294 LOG_DEBUG(
"get v24: args='%s'\r\n", args);
295 if (args == NULL || args[0] ==
'\0')
297 LOG_PLAIN(
"usage: get v24 <subcmd>\r\n");
308 if (strncmp(args,
v24_subcmds[i].name, len) == 0 && (args[len] ==
' ' || args[len] ==
'\0'))
310 const char* sub_args = args[len] ==
' ' ? args + len + 1 :
"";
315 LOG_PLAIN(
"unknown v24 subcmd: '%s'\r\n", args);
320 if (args == NULL || args[0] ==
'\0')
322 LOG_PLAIN(
"usage: set loglevel <error|info|debug|trace>\r\n");
327 if (sscanf(args,
"%15s", level_name) != 1)
329 LOG_PLAIN(
"usage: set loglevel <error|info|debug|trace>\r\n");
335 if (strcmp(level_name,
loglevels[i].name) == 0)
343 LOG_PLAIN(
"unknown loglevel: '%s'\r\n", level_name);
344 LOG_PLAIN(
"available loglevels: error, info, debug, trace\r\n");
349 if (args != NULL && args[0] !=
'\0')
362 event_t status_event = {.
type =
EV_REBOOT, .data.ptr = NULL, .data_len = 0, .is_inline =
false};
369 memcpy(ip_event_data.
value.
ip, ip_addr, 4);
373 .data_len =
sizeof(ip_event_data),
376 memcpy(ip_event.
data.
bytes, &ip_event_data,
sizeof(ip_event_data));
382 if (args != NULL && args[0] !=
'\0')
384 LOG_PLAIN(
"usage: get net ip.local\r\n");
396 LOG_PLAIN(
"usage: set net ip 192.168.29.2/24\r\n");
405 if (args != NULL && args[0] !=
'\0')
407 LOG_PLAIN(
"usage: get net ip.remote\r\n");
418 LOG_PLAIN(
"usage: set net ip.remote 192.168.29.2\r\n");
426 if (args != NULL && args[0] !=
'\0')
428 LOG_PLAIN(
"usage: get net ip.gateway\r\n");
439 LOG_PLAIN(
"usage: set net ip.gateway 192.168.29.1\r\n");
451 .data_len =
sizeof(get_request),
454 memcpy(event.data.bytes, &get_request,
sizeof(get_request));
464 .data_len =
sizeof(set_request),
467 memcpy(event.data.bytes, &set_request,
sizeof(set_request));
473 if (args != NULL && args[0] !=
'\0')
475 LOG_PLAIN(
"usage: get net udp.port.local\r\n");
486 LOG_PLAIN(
"usage: set net udp.port.local 6969\r\n");
494 if (args != NULL && args[0] !=
'\0')
496 LOG_PLAIN(
"usage: get net udp.port.remote\r\n");
508 LOG_PLAIN(
"usage: set net udp.port.remote 6969\r\n");
516 LOG_DEBUG(
"get net: args='%s'\r\n", args);
517 if (args == NULL || args[0] ==
'\0')
519 LOG_PLAIN(
"usage: get net <subcmd>\r\n");
530 if (strncmp(args,
net_subcmds[i].name, len) == 0 && (args[len] ==
' ' || args[len] ==
'\0'))
532 const char* sub_args = args[len] ==
' ' ? args + len + 1 :
"";
537 LOG_PLAIN(
"unknown net subcmd: '%s'\r\n", args);
547 switch (parser_result)
554 LOG_PLAIN(
"unknown pin: '%s'\r\n", pin_name);
557 LOG_PLAIN(
"pin '%s' is input-only\r\n", pin_name);
572 gpio_set_dir(pin->
gpio_num, GPIO_OUT);
580 if (args == NULL || args[0] ==
'\0')
582 LOG_PLAIN(
"usage: set net <subcmd> <args>\r\n");
593 if (strncmp(args,
net_subcmds[i].name, len) == 0 && (args[len] ==
' ' || args[len] ==
'\0'))
595 const char* sub_args = args[len] ==
' ' ? args + len + 1 :
"";
600 LOG_PLAIN(
"unknown net subcmd: '%s'\r\n", args);
610 switch (parser_result)
616 LOG_PLAIN(
"unknown pin: '%s'\r\n", pin_name);
631 if (gpio_get_function(pin->
gpio_num) != GPIO_FUNC_SIO)
634 gpio_set_dir(pin->
gpio_num, GPIO_IN);
637 else if (!gpio_is_dir_out(pin->
gpio_num))
642 int value = gpio_get(pin->
gpio_num);
643 bool is_output = gpio_is_dir_out(pin->
gpio_num);
646 is_output ?
"OUT" :
"IN");
651 if (args == NULL || args[0] ==
'\0')
653 LOG_PLAIN(
"usage: set <category> <args>\r\n");
664 if (strncmp(args,
categories[i].name, len) == 0 && args[len] ==
' ')
670 LOG_PLAIN(
"unknown set category: '%s'\r\n", args);
675 if (args == NULL || args[0] ==
'\0')
677 LOG_PLAIN(
"usage: get <category> <args>\r\n");
688 if (strncmp(args,
categories[i].name, len) == 0 && (args[len] ==
' ' || args[len] ==
'\0'))
690 const char* cat_args = args[len] ==
' ' ? args + len + 1 :
"";
695 LOG_PLAIN(
"unknown get category: '%s'\r\n", args);
722 size_t len = strlen(
commands[i].name);
735 LOG_PLAIN(
"\r\nSet/Get Categories:\r\n");
755 for (
size_t i = 0; i <
NUM_PINS; i++)
773 LOG_PLAIN(
" error, info, debug, trace\r\n");
779 event_t status_event = {.
type =
EV_STATUS, .data.ptr = NULL, .data_len = 0, .is_inline =
false};
785 if (args != NULL && args[0] !=
'\0')
790 event_t mem_event = {.
type =
EV_MEM, .data.ptr = NULL, .data_len = 0, .is_inline =
false};
796 if (args != NULL && args[0] !=
'\0')
801 wiz_NetInfo net_info;
802 wizchip_getnetinfo(&net_info);
803 LOG_PLAIN(
"ip=%u.%u.%u.%u gw=%u.%u.%u.%u\r\n", net_info.ip[0], net_info.ip[1], net_info.ip[2],
804 net_info.ip[3], net_info.gw[0], net_info.gw[1], net_info.gw[2], net_info.gw[3]);
811 if (sscanf(args,
"%15s", pin_name) != 1)
820 LOG_PLAIN(
"unknown pin: '%s'\r\n", pin_name);
825 bool is_output = gpio_is_dir_out(gpio_num);
826 int value = gpio_get(gpio_num);
828 LOG_PLAIN(
"Pin %s (GPIO %u):\r\n", pin_name, gpio_num);
829 LOG_PLAIN(
" Direction: %s\r\n", is_output ?
"OUTPUT" :
"INPUT");
831 LOG_PLAIN(
" Function: %d\r\n", gpio_get_function(gpio_num));
851 LOG_PLAIN(
"error: command too long\r\n");
854 if (parse_result !=
E2S_OK)
856 LOG_PLAIN(
"error: invalid command line\r\n");
862 if (strcmp(cmd,
commands[i].name) == 0)
869 LOG_PLAIN(
"unknown: '%s' (try 'help')\r\n", cmd);
static const V24_BAUDRATE_T v24_baudrates[]
static void cat_v24_set(const char *args)
static void dispatch_v24_polarities(const V24_POLARITIES_T *polarities)
static void subcmd_get_udp_port_local(const char *args)
static void cmd_reboot(const char *args)
static void dispatch_set_udp_port(const event_queue_data_types_t type, uint16_t port)
static void subcmd_get_udp_port_remote(const char *args)
static void subcmd_get_ip_gateway(const char *args)
static void subcmd_set_udp_port_remote(const char *args)
void(* category_set_handler_t)(const char *args)
static void cmd_help(const char *args)
void handle_cli_line(const char *line)
Parse and execute one CLI input line.
static const loglevel_entry_t loglevels[]
const char * get_command_name(int index)
Return command name by table index.
static void cmd_mem(const char *args)
static void subcmd_get_v24_clockmode(const char *args)
static void subcmd_set_ip_gateway(const char *args)
static void subcmd_set_v24_baudrate(const char *args)
static void cmd_status(const char *args)
static void subcmd_get_ip_remote(const char *args)
#define NUM_V24_BAUDRATES
static void cmd_set(const char *args)
static void dispatch_get_request(event_queue_data_types_t type, event_type_t event_type)
static void cat_gpio_get(const char *args)
static void cat_net_get(const char *args)
#define MAX_ARG_BUFFER_LEN
static const category_t categories[]
static void cmd_save(const char *args)
static void cat_loglevel_get(const char *args)
static void subcmd_set_ip_local(const char *args)
void(* subcmd_set_handler_t)(const char *args)
static void cmd_net(const char *args)
static void cmd_get(const char *args)
void(* category_get_handler_t)(const char *args)
static void cmd_pininfo(const char *args)
static void dispatch_get_udp_port(const event_queue_data_types_t type)
static const subcmd_t v24_subcmds[]
void(* subcmd_get_handler_t)(const char *args)
#define MAX_CMD_BUFFER_LEN
static const command_t commands[]
static void dispatch_ip(const uint8_t *ip_addr, const event_queue_data_types_t type)
static void subcmd_get_v24_baudrate(const char *args)
static void dispatch_v24_baudrate(const V24_BAUDRATE_T *baudrate)
static const subcmd_t net_subcmds[]
static void subcmd_get_v24_inverted(const char *args)
static void subcmd_set_ip_remote(const char *args)
static void cat_v24_get(const char *args)
static void cat_net_set(const char *args)
static void cmd_wipe(const char *args)
static void subcmd_set_v24_clockmode(const char *args)
static void subcmd_set_v24_inverted(const char *args)
static void subcmd_get_ip_local(const char *args)
static void subcmd_set_udp_port_local(const char *args)
void(* cmd_handler_t)(const char *args)
static void cat_gpio_set(const char *args)
static void cat_loglevel_set(const char *args)
e2s_error_t parse_set_v24_baudrate(const char *args, V24_BAUDRATE_T *baudrate)
Parse V.24 baudrate argument.
e2s_error_t cli_parse(const char *line, char *cmd, size_t cmd_cap, char *args, size_t args_cap)
Split one CLI line into command and argument string.
e2s_error_t parse_set_ip_args(const char *args, uint8_t ip_addr[4], uint8_t netmask[4])
Parse ip_addr and optional netmask values.
e2s_error_t parse_get_args(const char *args, char *pin_name, const pin_info_t **pin)
Parse get command arguments and resolve pin metadata.
e2s_error_t parse_set_v24_clockmode(const char *args, bool *clockmode)
Parse V.24 tx clock mode argument.
const pin_info_t * find_pin(const char *name)
Lookup pin metadata by name.
static const pin_info_t pin_table[]
e2s_error_t parse_set_udp_port_remote_args(const char *args, uint16_t *port)
Parse remote UDP port argument.
e2s_error_t parse_set_gpio_args(const char *args, char *pin_name, int *value, const pin_info_t **pin)
Parse GPIO set command arguments.
const pin_info_t * get_pin_table(void)
Return pointer to static pin metadata table.
e2s_error_t parse_set_udp_port_local_args(const char *args, uint16_t *port)
Parse local UDP port argument.
e2s_error_t parse_set_ip_remote_args(const char *args, uint8_t ip_addr[4])
Parse remote ip_addr argument.
e2s_error_t parse_set_v24_polarities(const char *args, V24_POLARITIES_T *polarities)
Parse V.24 polarities argument list.
log_level_t get_loglevel(void)
Get current global log level.
static const char * log_level_tag(log_level_t level)
Get printable tag for a log level.
void set_loglevel(log_level_t level)
Set current global log level.
log_level_t
Log verbosity levels.
e2s_error_t
Common error codes returned by ether2ser modules.
@ E2S_ERR_CLI_UNKNOWN_PIN
@ E2S_ERR_CLI_LINE_TRUNCATED
@ E2S_ERR_CLI_PIN_INPUT_ONLY
bool event_queue_push(const event_t *event_entry)
Enqueue an event.
event_queue_data_types_t
Typed payload selector for configuration-oriented events.
event_type_t
Event type identifiers.
Combined TX and RX polarity configuration.
category_set_handler_t set_handler
category_get_handler_t get_handler
Generic event payload wrapper for network/V.24 config operations.
V24_POLARITIES_T polarities
event_queue_data_types_t id
union event_queue_data_t::@0 value
Pin metadata entry used by CLI lookup and validation.
subcmd_set_handler_t set_handler
subcmd_get_handler_t get_handler
V24_BAUDRATE_T
Supported synchronous V.24 baudrates.