/* ** Copyright 2023 Tjitte van der Ploeg, tjitte@tpee.nl ** ** This file is part of the OpenBoost firmware. ** The Open-SEC firmware is free software: you can redistribute ** it and/or modify it under the terms of the GNU General Public License ** as published by the Free Software Foundation, either version 3 of the ** License, or (at your option) any later version. The Open-SEC firmware is ** distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ** without even the implied warranty of MERCHANTABILITY or FITNESS FOR A ** PARTICULAR PURPOSE. See the GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License along ** with this program. If not, see . */ #include "terminal.h" // Private types typedef struct _terminal_callback_struct { const char *command; const char *help; const char *arg_names; void(*cbf)(int argc, const char **argv); } terminal_callback_struct; // Private variables static terminal_callback_struct callbacks[CALLBACK_LEN]; static int callback_write = 0; void terminal_process_string(char *str) { enum { kMaxArgs = 64 }; int argc = 0; char *argv[kMaxArgs]; char *p2 = strtok(str, " "); while (p2 && argc < kMaxArgs) { argv[argc++] = p2; p2 = strtok(0, " "); } if (argc == 0) { modCommandsPrintf("No command received\n"); return; } if (strcmp(argv[0], "ping") == 0) { modCommandsPrintf("pong\n"); } else if (strcmp(argv[0], "status") == 0) { modCommandsPrintf("-----BMS Status-----"); } else if (strcmp(argv[0], "sens") == 0) { modCommandsPrintf("----- Sensors -----"); modCommandsPrintf("Input Current: %5.3f A", meter.Iind *1e-3); modCommandsPrintf("Output Current: %5.3f A", meter.Ihigh *1e-3); modCommandsPrintf("Input Voltage: %5.3f V", meter.Vlow *1e-3); modCommandsPrintf("Output Voltage: %5.3f V", meter.Vhigh *1e-3); } else if (strcmp(argv[0], "config") == 0) { modCommandsPrintf("--- MPPT Configuration ---"); } else if (strcmp(argv[0], "config_default") == 0) { modCommandsPrintf("--Restoring default config--"); if(modConfigStoreDefaultConfig()) modCommandsPrintf("Succesfully restored config, new config wil be used on powercycle (or use config_read to apply it now)."); else modCommandsPrintf("Error restored config."); modCommandsPrintf(" "); } else if (strcmp(argv[0], "config_write") == 0) { modCommandsPrintf("--- Writing config ---"); if(modConfigStoreConfig()) modCommandsPrintf("Succesfully written config."); else modCommandsPrintf("Error writing config."); modCommandsPrintf(" "); } else if (strcmp(argv[0], "config_read") == 0) { modCommandsPrintf("--- Reading config ---"); if(modConfigLoadConfig()) modCommandsPrintf("Succesfully read config."); else modCommandsPrintf("Error reading config."); modCommandsPrintf(" "); } else if (strcmp(argv[0], "hwinfo") == 0) { modCommandsPrintf("------- BMS Info -------"); } else if (strcmp(argv[0], "reboot") == 0) { modCommandsPrintf("------ Rebooting BMS ------"); NVIC_SystemReset(); } else if (strcmp(argv[0], "bootloader_erase") == 0) { //modCommandsPrintf("------ erasing new app space ------"); //if(modFlashEraseNewAppData(0x00002000) == HAL_OK) // modCommandsPrintf("--Erase done."); //else // modCommandsPrintf("--Erase error."); } else if (strcmp(argv[0], "bootloader_jump") == 0) { //modFlashJumpToBootloader(); } else if (strcmp(argv[0], "help") == 0) { modCommandsPrintf("------- Start of help -------"); //TODO Write help message for (int i = 0;i < callback_write;i++) { if (callbacks[i].arg_names) { modCommandsPrintf("%s %s", callbacks[i].command, callbacks[i].arg_names); } else { modCommandsPrintf(callbacks[i].command); } if (callbacks[i].help) { modCommandsPrintf(" %s", callbacks[i].help); } else { modCommandsPrintf(" There is no help available for this command."); } } modCommandsPrintf(" "); } else { bool found = false; for (int i = 0;i < callback_write;i++) { if (strcmp(argv[0], callbacks[i].command) == 0) { callbacks[i].cbf(argc, (const char**)argv); found = true; break; } } if (!found) { modCommandsPrintf("Invalid command: %s\n type help to list all available commands\n", argv[0]); } } } /** * Register a custom command callback to the terminal. If the command * is already registered the old command callback will be replaced. * * @param command * The command name. * * @param help * A help text for the command. Can be NULL. * * @param arg_names * The argument names for the command, e.g. [arg_a] [arg_b] * Can be NULL. * * @param cbf * The callback function for the command. */ void terminal_register_command_callback( const char* command, const char *help, const char *arg_names, void(*cbf)(int argc, const char **argv)) { int callback_num = callback_write; for (int i = 0;i < callback_write;i++) { // First check the address in case the same callback is registered more than once. if (callbacks[i].command == command) { callback_num = i; break; } // Check by string comparison. if (strcmp(callbacks[i].command, command) == 0) { callback_num = i; break; } } callbacks[callback_num].command = command; callbacks[callback_num].help = help; callbacks[callback_num].arg_names = arg_names; callbacks[callback_num].cbf = cbf; if (callback_num == callback_write) { callback_write++; if (callback_write >= CALLBACK_LEN) { callback_write = 0; } } } /* defaultConfig.cellBalanceDifferenceThreshold = 0.01f; // Start balancing @ 5mV difference, stop if below */