Open FFBoard
Open source force feedback firmware
SystemCommands.cpp
Go to the documentation of this file.
1/*
2 * SystemCommands.cpp
3 *
4 * Created on: 30.11.2021
5 * Author: Yannick
6 */
7
8#include "SystemCommands.h"
9#include "PersistentStorage.h"
10#include "FFBoardMain.h"
11#include "voltagesense.h"
12#include <malloc.h>
13#include "constants.h"
14#include "task.h"
15#include "FreeRTOSConfig.h"
18//extern static const uint8_t SW_VERSION_INT[3];
19
20
21bool SystemCommands::debugMode = false;
24
26 .name = "System Commands" ,
27 .id = CLSID_SYSTEM,
28 .visibility = ClassVisibility::hidden
29 };
30
32 return info;
33}
34
35SystemCommands::SystemCommands() : CommandHandler(CMDCLSTR_SYS, CMDCLSID_SYS) {
37 //CommandHandler::registerCommands();
39
40}
41
43 systemCommandsInstance = nullptr;
44}
45
46
48 CommandHandler::registerCommand("help", FFBoardMain_commands::help, "Print system help",CMDFLAG_STR_ONLY);
49 CommandHandler::registerCommand("save", FFBoardMain_commands::save, "Write all settings to flash",CMDFLAG_GET);
50 CommandHandler::registerCommand("reboot", FFBoardMain_commands::reboot, "Reset chip",CMDFLAG_GET);
51 CommandHandler::registerCommand("dfu", FFBoardMain_commands::dfu, "reboot into DFU bootloader",CMDFLAG_GET);
52 CommandHandler::registerCommand("lsmain", FFBoardMain_commands::lsmain, "List available mainclasses",CMDFLAG_GET);
53 CommandHandler::registerCommand("lsactive", FFBoardMain_commands::lsactive, "List active classes (Fullname:clsname:inst:clsid:idx)",CMDFLAG_GET);
54 CommandHandler::registerCommand("vint", FFBoardMain_commands::vint, "Internal voltage(mV)",CMDFLAG_GET);
55 CommandHandler::registerCommand("vext", FFBoardMain_commands::vext, "External voltage(mV)",CMDFLAG_GET);
56 CommandHandler::registerCommand("main", FFBoardMain_commands::main, "Query or change mainclass",CMDFLAG_GET | CMDFLAG_SET);
57 CommandHandler::registerCommand("swver", FFBoardMain_commands::swver, "Firmware version",CMDFLAG_GET);
58 CommandHandler::registerCommand("hwtype", FFBoardMain_commands::hwtype, "Hardware type",CMDFLAG_GET);
59 CommandHandler::registerCommand("flashraw", FFBoardMain_commands::flashraw, "Write value to flash address",CMDFLAG_SETADR | CMDFLAG_GETADR);
60 CommandHandler::registerCommand("flashdump", FFBoardMain_commands::flashdump, "Read all flash variables (val:adr)",CMDFLAG_GET);
61 CommandHandler::registerCommand("errors", FFBoardMain_commands::errors, "Read error states",CMDFLAG_GET);
62 CommandHandler::registerCommand("errorsclr", FFBoardMain_commands::errorsclr, "Reset errors",CMDFLAG_GET);
63 CommandHandler::registerCommand("heapfree", FFBoardMain_commands::heapfree, "Memory info",CMDFLAG_GET);
64#if configUSE_STATS_FORMATTING_FUNCTIONS> 0
65 CommandHandler::registerCommand("taskstats", FFBoardMain_commands::taskstats, "Task stats",CMDFLAG_GET);
66#endif
67 CommandHandler::registerCommand("format", FFBoardMain_commands::format, "set format=1 to erase all stored values",CMDFLAG_SET);
68 CommandHandler::registerCommand("debug", FFBoardMain_commands::debug, "Enable or disable debug commands",CMDFLAG_SET | CMDFLAG_GET);
69 CommandHandler::registerCommand("devid", FFBoardMain_commands::devid, "Get chip dev id and rev id",CMDFLAG_GET);
70 CommandHandler::registerCommand("name", CommandHandlerCommands::name, "name of class",CMDFLAG_GET|CMDFLAG_STR_ONLY);
71 CommandHandler::registerCommand("cmdinfo", CommandHandlerCommands::cmdinfo, "Flags of a command id (adr). -1 if cmd id invalid",CMDFLAG_GETADR);
72 CommandHandler::registerCommand("uid", FFBoardMain_commands::uid, "Get 96b chip uid. Adr0-2 sel blk",CMDFLAG_GET | CMDFLAG_GETADR);
73 CommandHandler::registerCommand("temp", FFBoardMain_commands::temp, "Chip temperature in C",CMDFLAG_GET);
74}
75
76// Choose lower optimize level because the compiler likes to blow up this function
77__attribute__((optimize("-O1")))
78CommandStatus SystemCommands::internalCommand(const ParsedCommand& cmd,std::vector<CommandReply>& replies){
80
81 if(flag != CommandStatus::NOT_FOUND){
82 return flag;
83 }else{
84 flag = CommandStatus::OK;
85 }
86
87 switch(static_cast<FFBoardMain_commands>(cmd.cmdId))
88 {
90 {// help
91 if(cmd.type == CMDtype::info){
92 replies.emplace_back(this->getCsvHelpstring());
93 }else{
94 std::string itfHelp = "";
95 if(cmd.originalInterface){
96 itfHelp = cmd.originalInterface->getHelpstring() + "\n";
97 }
98 std::string reply = itfHelp + "Available classes (use cls.0.help for more info):\n";
99 //std::string reply = "";
101 CmdHandlerInfo* info = handler->getCommandHandlerInfo();
102 reply += std::string(info->clsname) + "." + std::to_string(info->instance)+"\n";
103 }
104 reply += "\n"+this->getCommandsHelpstring();
105 replies.emplace_back(reply);
106 }
107
108 break;
109 }
110
113 handler->saveFlash();
114 }
115 break;
116
118 NVIC_SystemReset();
119 break;
120
122 RebootDFU();
123 break;
125 mainchooser.replyAvailableClasses(replies,mainclass->getSelectionID());
126 break;
127
129 {
130 replies.emplace_back(getIntV());
131 break;
132 }
133
135 return handleGetSet(cmd, replies, SystemCommands::debugMode);
136
138 {
139 replies.emplace_back(getExtV());
140 break;
141 }
142
144 {
145 if(cmd.type == CMDtype::get){
146 uint16_t buf=mainclass->getInfo().id;
147 Flash_Read(ADR_CURRENT_CONFIG, &buf);
148 replies.emplace_back(buf);
149 }else if(cmd.type == CMDtype::set){
150 if(mainchooser.isValidClassId(cmd.val)){
151 Flash_Write(ADR_CURRENT_CONFIG, (uint16_t)cmd.val);
152 if(cmd.val != mainclass->getInfo().id){
153 NVIC_SystemReset(); // Reboot
154 }
155 }
156 }
157 break;
158 }
160 {
161 replyErrors(replies);
162 break;
163 }
165 replyFlashDump(replies);
166 break;
167
169 {
170 if(cmd.type == CMDtype::setat){
171 Flash_Write(cmd.adr, cmd.val);
172
173 }else if(cmd.type == CMDtype::getat){
174 CommandReply reply;
176 uint16_t val;
177 if(Flash_Read(cmd.adr,&val)){
178 reply.val=val;
179 }
180 replies.push_back(reply);
181 }
182 break;
183 }
184
187 break;
188
190 {
191 CommandReply reply;
193
194 extern const uint8_t SW_VERSION_INT[3];
195 reply.reply += std::to_string(SW_VERSION_INT[0]) + "." + std::to_string(SW_VERSION_INT[1]) + "." + std::to_string(SW_VERSION_INT[2]);
196
197 reply.val = (SW_VERSION_INT[0]<<16) | (SW_VERSION_INT[1] << 8) | (SW_VERSION_INT[2]);
198 replies.push_back(reply);
199 break;
200 }
201
203 {
204 replies.emplace_back(HW_TYPE,HW_TYPE_INT);
205 //replies.emplace_back(HAL_GetDEVID());
206 break;
207 }
209 {
210 replies.emplace_back(HAL_GetDEVID(),HAL_GetREVID());
211 break;
212 }
213
214
215 case FFBoardMain_commands::mallinfo: // UNUSED since freertos
216 {
217 CommandReply reply;
218 struct mallinfo info = mallinfo();
219 reply.adr = info.uordblks;
220 reply.val = info.uordblks;
221 reply.reply +="Usage: ";
222 reply.reply += std::to_string(info.uordblks);
223 reply.reply +=" Size: ";
224 reply.reply +=std::to_string(info.arena);
226 replies.push_back(reply);
227 break;
228 }
229
231 {
232 replies.emplace_back(xPortGetFreeHeapSize(),xPortGetMinimumEverFreeHeapSize());
233 break;
234 }
235#if configUSE_STATS_FORMATTING_FUNCTIONS>0
237 {
238 char repl[800];
239 vTaskGetRunTimeStats(repl);
240 replies.emplace_back("\n"+std::string(repl));
241 break;
242 }
243#endif
245 {
247
248 ClassIdentifier i = handler->getInfo();
249 CmdHandlerInfo* hi = handler->getCommandHandlerInfo();
250 CommandReply reply;
252 reply.adr = hi->instance;
253 reply.val = hi->clsTypeid;
254 reply.reply += std::string(i.name)+ ":" + hi->clsname + ":" + std::to_string(hi->instance) + ":" + std::to_string(i.id) + ":" + std::to_string(hi->commandHandlerID);
255 replies.push_back(reply);
256
257 }
258 break;
259 }
261 if(cmd.type == CMDtype::set && cmd.val==1){
262
263 if(Flash_Format()){
264 flag = CommandStatus::OK;
265 }else{
266 flag = CommandStatus::ERR;
267 }
268
269 }
270 break;
272 if(cmd.type == CMDtype::get){
273 replies.emplace_back((uint64_t)HAL_GetUIDw0() | (uint64_t)HAL_GetUIDw1() << 32,HAL_GetUIDw2());
274 }else if(cmd.type == CMDtype::getat){
275 if(cmd.adr == 0){
276 replies.emplace_back(HAL_GetUIDw0());
277 }else if(cmd.adr == 1){
278 replies.emplace_back(HAL_GetUIDw1());
279 }else if(cmd.adr == 2){
280 replies.emplace_back(HAL_GetUIDw2());
281 }
282 }
283 break;
285 {
286 replies.emplace_back(getChipTemp());
287 break;
288 }
289
290
291 default:
293 break;
294 }
295 return flag;
296}
297
298/*
299 * Prints a formatted flash dump to the reply string
300 */
301void SystemCommands::replyFlashDump(std::vector<CommandReply>& replies){
302 std::vector<std::tuple<uint16_t,uint16_t>> result;
303 Flash_Dump(&result,false);
304
305 for(auto entry : result){
306 CommandReply reply;
307 uint16_t adr;
308 uint16_t val;
309 std::tie(adr,val) = entry;
310 //reply.reply += std::to_string(adr) + ":" + std::to_string(val) + "\n";
311 reply.adr = adr;
312 reply.val = val;
314 replies.push_back(reply);
315 }
316}
317
318/*
319 * Prints a formatted list of error conditions
320 */
321void SystemCommands::replyErrors(std::vector<CommandReply>& replies){
322 std::span<Error> errors = ErrorHandler::getErrors();
323 if(errors.size() == 0){
324 CommandReply reply;
325 reply.reply += "None";
327 replies.push_back(reply);
328 return;
329 }
330
331 for(Error error : errors){
332 CommandReply reply;
333 reply.reply += error.toString() + "\n";
334 reply.val = (uint32_t)error.code;
336 replies.push_back(reply);
337 }
338
340}
CommandStatus
uint8_t adr
FFBoardMain * mainclass
__attribute__((optimize("-O1"))) CommandStatus SystemCommands
ClassChooser< FFBoardMain > mainchooser
FFBoardMain_commands
uint16_t getSelectionID()
void registerCommand(const char *cmd, const ID cmdid, const char *help=nullptr, uint32_t flags=0)
virtual CommandStatus internalCommand(const ParsedCommand &cmd, std::vector< CommandReply > &replies)
static std::vector< CommandHandler * > & getCommandHandlers()
std::string reply
CommandReplyType type
static std::span< Error > getErrors()
static void clearTemp()
static void clearAll()
virtual const ClassIdentifier getInfo()
Definition: FFBoardMain.cpp:25
static std::vector< PersistentStorage * > & getFlashHandlers()
static SystemCommands * systemCommandsInstance
static ClassIdentifier info
virtual ~SystemCommands()
static bool errorPrintingEnabled
static bool debugMode
static void replyErrors(std::vector< CommandReply > &replies)
static void replyFlashDump(std::vector< CommandReply > &replies)
const ClassIdentifier getInfo()
Command handlers always have class infos. Works well with ChoosableClass.
static const uint8_t SW_VERSION_INT[3]
Definition: constants.h:11
bool Flash_Format()
void Flash_Dump(std::vector< std::tuple< uint16_t, uint16_t > > *result, bool includeAll=false)
bool Flash_Write(uint16_t adr, uint16_t dat)
bool Flash_Read(uint16_t adr, uint16_t *buf, bool checkempty=true)
const char * name
const char * clsname
uint16_t commandHandlerID
const uint16_t clsTypeid
int32_t getChipTemp()
int32_t getIntV()
int32_t getExtV()