238 lines
6.8 KiB
C
238 lines
6.8 KiB
C
#include "os_cli.h"
|
|
#include "os_app.h"
|
|
#include "os_input.h"
|
|
#include "os_gfx.h"
|
|
#include "os_oled.h"
|
|
#include "os_status.h"
|
|
#include "sys_uart.h"
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include "esp_console.h"
|
|
#include "esp_system.h"
|
|
#include "esp_log.h"
|
|
#include "freertos/FreeRTOS.h"
|
|
#include "freertos/task.h"
|
|
|
|
static const char *TAG = "SYS_CLI";
|
|
|
|
static int cmd_uart(int argc, char **argv)
|
|
{
|
|
if (argc < 2) {
|
|
printf("Usage: uart <send <msg> | baud <rate> | stats | clear>\n");
|
|
return 1;
|
|
}
|
|
|
|
if (strcmp(argv[1], "send") == 0 && argc >= 3) {
|
|
sys_uart_write_str(argv[2]);
|
|
sys_uart_write_str("\r\n");
|
|
printf("Sent over UART TX: %s\n", argv[2]);
|
|
return 0;
|
|
} else if (strcmp(argv[1], "baud") == 0 && argc >= 3) {
|
|
uint32_t baud = (uint32_t)strtoul(argv[2], NULL, 10);
|
|
if (baud > 0 && sys_uart_set_baud_rate(baud) == ESP_OK) {
|
|
printf("UART baud rate changed to %lu\n", (unsigned long)baud);
|
|
return 0;
|
|
} else {
|
|
printf("Failed to set baud rate\n");
|
|
return 1;
|
|
}
|
|
} else if (strcmp(argv[1], "stats") == 0) {
|
|
uint32_t rx = 0, tx = 0;
|
|
sys_uart_get_stats(&rx, &tx);
|
|
printf("\n=== UART Status (TX: GPIO 21, RX: GPIO 20) ===\n");
|
|
printf("Active Baud Rate: %lu\n", (unsigned long)sys_uart_get_baud_rate());
|
|
printf("Total RX Bytes: %lu\n", (unsigned long)rx);
|
|
printf("Total TX Bytes: %lu\n", (unsigned long)tx);
|
|
return 0;
|
|
} else if (strcmp(argv[1], "clear") == 0) {
|
|
sys_uart_clear_rx_buffer();
|
|
printf("UART RX buffer cleared\n");
|
|
return 0;
|
|
}
|
|
|
|
printf("Unknown uart sub-command\n");
|
|
return 1;
|
|
}
|
|
|
|
static int cmd_ps(int argc, char **argv)
|
|
{
|
|
printf("\n=== Running FreeRTOS Tasks ===\n");
|
|
char task_buf[512];
|
|
vTaskList(task_buf);
|
|
printf("TaskName\tStatus\tPrio\tStack\tNum\n");
|
|
printf("%s\n", task_buf);
|
|
return 0;
|
|
}
|
|
|
|
static int cmd_free(int argc, char **argv)
|
|
{
|
|
printf("\n=== Memory Allocation ===\n");
|
|
printf("Current Free Heap: %lu bytes\n", (unsigned long)esp_get_free_heap_size());
|
|
printf("Minimum Free Heap: %lu bytes\n", (unsigned long)esp_get_minimum_free_heap_size());
|
|
return 0;
|
|
}
|
|
|
|
static int cmd_app(int argc, char **argv)
|
|
{
|
|
if (argc < 2) {
|
|
printf("Usage: app <list | launch <id> | home>\n");
|
|
return 1;
|
|
}
|
|
|
|
if (strcmp(argv[1], "list") == 0) {
|
|
size_t count = sys_app_get_count();
|
|
printf("\n=== Registered Apps (%u) ===\n", (unsigned int)count);
|
|
for (size_t i = 0; i < count; i++) {
|
|
const sys_app_t *app = sys_app_get_by_index(i);
|
|
printf(" [%u] %-12s (ID: %s)\n", (unsigned int)i, app->name, app->id);
|
|
}
|
|
return 0;
|
|
} else if (strcmp(argv[1], "launch") == 0 && argc >= 3) {
|
|
esp_err_t err = sys_app_launch_by_id(argv[2]);
|
|
if (err == ESP_OK) {
|
|
printf("Launched app: %s\n", argv[2]);
|
|
} else {
|
|
printf("Failed to launch app: %s\n", argv[2]);
|
|
}
|
|
return 0;
|
|
} else if (strcmp(argv[1], "home") == 0) {
|
|
sys_app_launch_launcher();
|
|
printf("Switched to Home Launcher\n");
|
|
return 0;
|
|
}
|
|
|
|
printf("Unknown app sub-command\n");
|
|
return 1;
|
|
}
|
|
|
|
static int cmd_input(int argc, char **argv)
|
|
{
|
|
if (argc < 2) {
|
|
printf("Usage: input <click | double | long | home>\n");
|
|
return 1;
|
|
}
|
|
|
|
if (strcmp(argv[1], "click") == 0) {
|
|
sys_input_inject(INPUT_ACTION_CLICK);
|
|
} else if (strcmp(argv[1], "double") == 0) {
|
|
sys_input_inject(INPUT_ACTION_DOUBLE_CLICK);
|
|
} else if (strcmp(argv[1], "long") == 0) {
|
|
sys_input_inject(INPUT_ACTION_LONG_PRESS);
|
|
} else if (strcmp(argv[1], "home") == 0) {
|
|
sys_input_inject(INPUT_ACTION_HOLD_HOME);
|
|
} else {
|
|
printf("Invalid action\n");
|
|
return 1;
|
|
}
|
|
printf("Injected action: %s\n", argv[1]);
|
|
return 0;
|
|
}
|
|
|
|
static int cmd_reboot(int argc, char **argv)
|
|
{
|
|
printf("Restarting system...\n");
|
|
esp_restart();
|
|
return 0;
|
|
}
|
|
|
|
static int cmd_contrast(int argc, char **argv)
|
|
{
|
|
if (argc < 2) {
|
|
printf("Usage: contrast <0-255>\n");
|
|
return 1;
|
|
}
|
|
int val = atoi(argv[1]);
|
|
if (val < 0 || val > 255) {
|
|
printf("Value must be 0 to 255\n");
|
|
return 1;
|
|
}
|
|
oled_driver_set_contrast((uint8_t)val);
|
|
printf("Contrast set to %d\n", val);
|
|
return 0;
|
|
}
|
|
|
|
esp_err_t sys_cli_init(void)
|
|
{
|
|
esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT();
|
|
repl_config.prompt = "esp32c3-os> ";
|
|
repl_config.max_cmdline_args = 8;
|
|
repl_config.max_cmdline_length = 256;
|
|
|
|
esp_console_dev_usb_serial_jtag_config_t hw_config =
|
|
ESP_CONSOLE_DEV_USB_SERIAL_JTAG_CONFIG_DEFAULT();
|
|
esp_console_repl_t *repl = NULL;
|
|
esp_err_t err = esp_console_new_repl_usb_serial_jtag(&hw_config, &repl_config, &repl);
|
|
if (err != ESP_OK) {
|
|
ESP_LOGE(TAG, "Failed to create USB Serial/JTAG REPL: %s", esp_err_to_name(err));
|
|
return err;
|
|
}
|
|
|
|
esp_console_register_help_command();
|
|
|
|
const esp_console_cmd_t ps_cmd = {
|
|
.command = "ps",
|
|
.help = "List active FreeRTOS tasks and memory",
|
|
.hint = NULL,
|
|
.func = &cmd_ps,
|
|
};
|
|
esp_console_cmd_register(&ps_cmd);
|
|
|
|
const esp_console_cmd_t free_cmd = {
|
|
.command = "free",
|
|
.help = "Display system heap status",
|
|
.hint = NULL,
|
|
.func = &cmd_free,
|
|
};
|
|
esp_console_cmd_register(&free_cmd);
|
|
|
|
const esp_console_cmd_t app_cmd = {
|
|
.command = "app",
|
|
.help = "App management (list, launch <id>, home)",
|
|
.hint = "<list|launch|home>",
|
|
.func = &cmd_app,
|
|
};
|
|
esp_console_cmd_register(&app_cmd);
|
|
|
|
const esp_console_cmd_t input_cmd = {
|
|
.command = "input",
|
|
.help = "Simulate button input (click, double, long, home)",
|
|
.hint = "<click|double|long|home>",
|
|
.func = &cmd_input,
|
|
};
|
|
esp_console_cmd_register(&input_cmd);
|
|
|
|
const esp_console_cmd_t contrast_cmd = {
|
|
.command = "contrast",
|
|
.help = "Set OLED contrast (0-255)",
|
|
.hint = "<value>",
|
|
.func = &cmd_contrast,
|
|
};
|
|
esp_console_cmd_register(&contrast_cmd);
|
|
|
|
const esp_console_cmd_t reboot_cmd = {
|
|
.command = "reboot",
|
|
.help = "Reboot the MCU",
|
|
.hint = NULL,
|
|
.func = &cmd_reboot,
|
|
};
|
|
esp_console_cmd_register(&reboot_cmd);
|
|
|
|
const esp_console_cmd_t uart_cmd = {
|
|
.command = "uart",
|
|
.help = "Hardware UART control (send, baud, stats, clear)",
|
|
.hint = "<send|baud|stats|clear>",
|
|
.func = &cmd_uart,
|
|
};
|
|
esp_console_cmd_register(&uart_cmd);
|
|
|
|
err = esp_console_start_repl(repl);
|
|
if (err != ESP_OK) {
|
|
ESP_LOGE(TAG, "Failed to start USB Serial/JTAG REPL: %s", esp_err_to_name(err));
|
|
return err;
|
|
}
|
|
|
|
ESP_LOGI(TAG, "CLI shell initialized");
|
|
return ESP_OK;
|
|
}
|