Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed
Diff: src/command.cpp
- Revision:
- 42:3ae73b61f657
- Child:
- 43:291bbdba48f3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/command.cpp Sat Mar 09 21:01:45 2019 +0000 @@ -0,0 +1,780 @@ +//------------------------------------------------------------------------------- +// +// Treehouse Inc. +// Colorado Springs, Colorado +// +// Copyright (c) 2016 by Treehouse Designs Inc. +// +// This code is the property of Treehouse, Inc. (Treehouse) +// and may not be redistributed in any form without prior written +// permission of the copyright holder, Treehouse. +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// +//------------------------------------------------------------------------------- +// +// REVISION HISTORY: +// +// $Author: $ +// $Rev: $ +// $Date: $ +// $URL: $ +// +//------------------------------------------------------------------------------- + +#include "mbed.h" +#include "string.h" +#include "stdio.h" +#include "stdlib.h" +#include "ctype.h" +#include "serial.h" +#include "globals.h" +#include "math.h" +#include "parameters.h" +#include "all_io.h" +#include "boards.h" +#include "menu.h" +#include "command.h" + +unsigned int boardsActive = ALLON; +unsigned int boardMults = 32; +unsigned int commandData; +extern unsigned short my12; + +/************* FILE SCOPE VARIABLES ************************/ +char setvalue = FALSE; +int endOfCommand = 0; +int commandError = 0; +int menuLevel = LEVEL_MAIN; +int readback = 0; + +/************************************************************ +* Routine: getDelimiter +* Input: none +* Output: none +* Description: +* searches for a delimiter and moves the buffer location +* to be just past it +* +**************************************************************/ +void getDelimiter(void) +{ + ++bufloc; + + while ((rxbuf[bufloc] != ' ') && + (rxbuf[bufloc] != ',') && + (rxbuf[bufloc] != '=') && + (rxbuf[bufloc] != 0 )) + { + bufloc++; + } +} + +/************************************************************ +* Routine: gethex +* Input: hex character +* Returns: hex integer +* Description: +* Converts a hex character to a value +**************************************************************/ +char gethex(char val) +{ + int retval; + switch(val) + { + case '0': + retval = 0; + break; + case '1': + retval = 1; + break; + case '2': + retval = 2; + break; + case '3': + retval = 3; + break; + case '4': + retval = 4; + break; + case '5': + retval = 5; + break; + case '6': + retval = 6; + break; + case '7': + retval = 7; + break; + case '8': + retval = 8; + break; + case '9': + retval = 9; + break; + case 'A': + retval = 10; + break; + case 'B': + retval = 11; + break; + case 'C': + retval = 12; + break; + case 'D': + retval = 13; + break; + case 'E': + retval = 14; + break; + case 'F': + retval = 15; + break; + default: + retval = 0; + break; + + } + return retval; +} + +/************************************************************ +* Routine: showfval +* Input: setval (GET or SET) +* value (float value to display) +* Output: none +* Description: +* Sends a floating point number (value) over the serial port +* if it is being retrieved (GET) +* +**************************************************************/ +void showfval(char setval,float value) +{ + if(!setval) + { + sprintf(strbuf," %4.9f",value); + sendSerial(strbuf); + } +} + +/************************************************************ +* Routine: showival +* Input: setval (GET or SET) +* value (integer value to display) +* Output: none +* Description: +* Sends an integer (value) over the serial port +* if it is being retrieved (GET) +* +**************************************************************/ +void showival(char setval, int value) +{ + if(!setval) + { + sprintf(strbuf," %i",value); + sendSerial(strbuf); + } +} +/************************************************************ +* Routine: showcval +* Input: setval (GET or SET) +* value (character to display) +* Output: none +* Description: +* Sends a character over the serial port +* if it is being retrieved (GET) +* +**************************************************************/ +void showcval(char setval, int value) +{ + if(!setval) + { + sprintf(strbuf," %c",(char)value); + sendSerial(strbuf); + } +} + +/************************************************************ +* Routine: showlval +* Input: setval (GET or SET) +* value (integer value to display) +* Output: none +* Description: +* Sends an long (value) over the serial port +* if it is being retrieved (GET) +* +**************************************************************/ +void showlval(char setval, long value) +{ + if(!setval) + { + sprintf(strbuf," %ld",value); + sendSerial(strbuf); + } +} + +/************************************************************ +* Routine: showuival +* Input: setval (GET or SET) +* value (integer value to display) +* Output: none +* Description: +* Sends an unsigned int (value) over the serial port +* if it is being retrieved (GET) +* +**************************************************************/ +void showuival(char setval, unsigned int value) +{ + if(!setval) + { + sprintf(strbuf," %u",value); + sendSerial(strbuf); + } +} + +/************************************************************ +* Routine: showhval +* Input: setval (GET or SET) +* value (hex integeger value to display) +* Output: none +* Description: +* Sends an integer (value) in hex over the serial port +* if it is being retrieved (GET) +* +**************************************************************/ +void showhval(char setval, int value) +{ + if(!setval) + { + if(serialStatus.computer) + sprintf(strbuf," %u",(unsigned int)value); + else + sprintf(strbuf," 0x%04x",value); + sendSerial(strbuf); + } +} + + +/************************************************************ +* Routine: getival +* Input: setval (GET or SET) +* Returns: the value if it is being SET or 0 if it is a GET +* Description: +* Gets an integer from the serial port connection. +* +**************************************************************/ +int getival(char setval) +{ + if (setval) + { + return atoi(&rxbuf[++bufloc]); + } + + return 0; +} + +/************************************************************ +* Routine: getcval +* Input: setval (GET or SET) +* Returns: the value if it is being SET or 0 if it is a GET +* Description: +* Gets an character from the serial port connection. +* +**************************************************************/ +int getcval(char setval) +{ + if(setval) + { + // skip one space + ++bufloc; + // skip spaces and the equals sign + while((rxbuf[bufloc] == ' ') || (rxbuf[bufloc] == '=')) + bufloc++; + return rxbuf[bufloc++]; + } + else + return 0; + +} +/************************************************************ +* Routine: getlval +* Input: setval (GET or SET) +* Returns: the value if it is being SET or 0 if it is a GET +* Description: +* Gets an long from the serial port connection. +* +**************************************************************/ +long getlval(char setval) +{ + if(setval) + return atol(&rxbuf[++bufloc]); + else + return 0; + +} + +/************************************************************ +* Routine: getfval +* Input: setval (GET or SET) +* Returns: the value if it is being SET or 0 if it is a GET +* Description: +* Gets an float from the serial port connection. +* +**************************************************************/ +float getfval(char setval) +{ + if(setval) + return atof(&rxbuf[++bufloc]); + else + return 0; +} + +/************************************************************ +* Routine: validateEntry +* Input: setval (GET or SET) +* limlo -- low limit +* limhi -- high limit +* address -- address in eeprom to use +* Returns: 0 if entry validates and is written +* 1 if entry fails +* Description: +* Gets or sets a value in eeprom at the address but only +* if it is between the limits will it write the value to +* eeprom +* +**************************************************************/ +int validateEntry(char setvalue, float limlo, float limhi, float *address) +{ + float val; + + if (setvalue) + { + val = getfval(SET); + + if ((val >= limlo) && (val <= limhi)) + { + *address = val; + } + else + { + showRangeError(0, 0, val); + return 0; + } + } + else + { + val = *address; + sprintf(strbuf, " %4.3f", val); + sendSerial(strbuf); + } + + return 1; +} + + +/************************************************************ +* Routine: validateEntry +* Input: setval (GET or SET) +* limlo -- low limit +* limhi -- high limit +* address -- address in eeprom to use +* +* Returns: FALSE if entry fails +* TRUE if entry validates and is written +* +* Description: +* Gets or sets a value in eeprom at the address but only +* if it is between the limits will it write the value to +* eeprom +* +**************************************************************/ +int validateInt(char setvalue, int limlo, int limhi, int *address) +{ + float val; + + if (setvalue) + { + val = getfval(SET); + + if ((val >= limlo) && (val <= limhi)) + { + *address = val; + } + else + { + showRangeError(1, val, 0); + return FALSE; + } + } + else + { + val = *address; + sprintf(strbuf, " %4.0f", val); + sendSerial(strbuf); + } + + return TRUE; +} + + +/************************************************************ +* Routine: parseCommand +* Input: setvalue (GET or SET), command buffer +* Returns: none +* Description: +* parses a command and gets the commandstring +**************************************************************/ +void parseCommand(char setvalue, char *commandString) +{ + int i, endofc; + char store; + + // Ignore any white space and the optional ';' character before the start of + // the command string (any ']' character is from the last command so skip that, + // too) + while ((isspace(rxbuf[bufloc])) || (rxbuf[bufloc] == ';') || (rxbuf[bufloc] == ']')) + { + bufloc++; + if ((rxbuf[bufloc] == 0x0D) || (rxbuf[bufloc] == 0)) break; + } + + if (setvalue) + { + // We need a value for SET so hitting the end is a problem + if ((rxbuf[bufloc] == 0) || (rxbuf[bufloc] == 0x0D)) + { + commandError = 1; + return; + } + } + + // Find the end of the command string + endofc = bufloc + 1; + + // White space, '[' and '?' all terminate the command string + while ((!isspace(rxbuf[endofc])) && (rxbuf[endofc] != '[') && (rxbuf[endofc] != '?')) + { + endofc++; + // (As does hitting the end of rxbuf!) + if ((rxbuf[endofc] == 0x0D) || (rxbuf[endofc] == 0)) break; + } + + // Save the character that marks the end of the command string + store = rxbuf[endofc]; + + // sprintf(strbuf, "store == %c\r\n", store); + // sendSerial(strbuf); + + // Command strings ending in '?' are readbacks + readback = ((store == '?') ? 1 : 0); + + // Set end to null character so string can now be copied + rxbuf[endofc] = 0; + + // Copy the command string into commandString + char commandStringBuf[80]; + char *tok; + strcpy(commandStringBuf, &rxbuf[bufloc]); + if(strstr(commandStringBuf, "=")){ + tok = strtok(commandStringBuf, "="); + strcpy(commandString, tok); + tok = strtok(NULL, "="); + commandData = atoi(tok); + } + else{ + strcpy(commandString, commandStringBuf); + } + + // Convert the command string to all uppercase characters + for (i = 0; i < strlen(commandString); i++) + { + commandString[i] = toupper(commandString[i]); + } + + // Replace the character we clobbered in rxbuf + rxbuf[endofc] = store; + + // Update bufloc to the end of the command string + bufloc = endofc; +} + +/************************************************************ +* Routine: doCommand +* Input: none +* Returns: none +* Description: +* This is the start of the command string. +**************************************************************/ +void doCommand(void) +{ + int ival; + unsigned int boardEnables; + + char commandString[80] = { 0 }; + + bufloc = 0; + commandError = 0; + + parseCommand(GET, commandString); + + if (!strcmp(commandString, "MENU")) + { + menuRedraw(NO_PROMPT); + } + else if (!strcmp(commandString, "HELP")) + { + menuRedraw(NO_PROMPT); + } + else if (!strcmp(commandString, "MAXB")) + // MAXB is used to get/set the max_boards value. + // The integer value of max_boards is used to select the appropriate lookup table. + { + if (readback) + { + sprintf(strbuf, " %d", max_boards); + sendSerial(strbuf); + } + else if (running == 1) + { + sprintf(strbuf, " Parameters may not be updated while running!"); + sendSerial(strbuf); + } + else + { + max_boards = commandData; + } + } + else if (!strcmp(commandString, "BRDS")) + // BRDS is used to get/set the wr_out value. + // The integer value of boardsActive is used to change wr_out via setBoardEnables(boardsActive). + // Slots 12 to 0 are activated with the wr_out signals + // wr_out[13] = slots[12:0] + { + if (readback) + { + sprintf(strbuf, " %d", boardsActive); + sendSerial(strbuf); + } + else if (running == 1) + { + sprintf(strbuf, " Parameters may not be updated while running!"); + sendSerial(strbuf); + } + else + { + boardsActive = commandData; + if(checkRange(boardsActive, 0, 8191) == 1){ + wr_out_code = setBoardEnables(boardsActive); + testing = TRUE; + }else{ + showRangeError(1, boardsActive, 0.0); + } + } + } + else if (!strcmp(commandString, "MULT")) + // MULT is used to get/set the en_out value. + // The integer value of boardMults is used to change en_out via setBoardWeights(boardMults). + // en_out are binary weighted signals that activate groups of DC-DC converters on the slot cards. + // en_out[6] = {en32, en16, en8, en4, en2, en1} + { + if (readback) + { + sprintf(strbuf, " %d", boardMults); + sendSerial(strbuf); + } + else if (running == 1) + { + sprintf(strbuf, " Parameters may not be updated while running!"); + sendSerial(strbuf); + } + else + { + boardMults = commandData; + if(checkRange(boardMults, 0, 63) == 1){ + en_out_code = setBoardWeights(boardMults); + testing = TRUE; + }else{ + showRangeError(1, boardMults, 0.0); + } + } + } + else if (!strcmp(commandString, "MY12")) + // MULT is used to get/set the en_out value. + // The integer value of boardMults is used to change en_out via setBoardWeights(boardMults). + // en_out are binary weighted signals that activate groups of DC-DC converters on the slot cards. + // en_out[6] = {en32, en16, en8, en4, en2, en1} + { + + if (readback) + { + sprintf(strbuf, " %d", my12); + sendSerial(strbuf); + }else{ + my12 = commandData; + testing = FALSE; + } + } + else if (!strcmp(commandString, "ALLOFF")) + { + my12 = 0; + running = FALSE; + testing = FALSE; + if(DEBUG){ + sprintf(strbuf, "wr_out_code=%d\r\n", wr_out_code); + sendSerial(strbuf); + } + } + else if (!strcmp(commandString, "ALLON")) + { + wr_out_code = setBoardEnables((unsigned int)ALLON); + testing = TRUE; + } + else if (!strcmp(commandString, "RUN")) + { + // Skip over any white space and the optional '[' character + while ((isspace(rxbuf[bufloc])) || (rxbuf[bufloc] == '[')) bufloc++; + + if(rxbuf[bufloc] == NULL){ + boardsActive = ALLON; + startConverter(boardsActive); + testing = FALSE; + } + else if (rxbuf[bufloc] == '0') + { + stopConverter(); + testing = FALSE; + } + else if ((rxbuf[bufloc] > '0') && (rxbuf[bufloc] < '0' + max_boards)) + { + ival = atoi(&rxbuf[bufloc]); + //ival--; + + if (running == 0) + { + boardsActive = ival; + startConverter(boardsActive); + testing = FALSE; + } + else + { + // Compare the board enable flags between registers + //boardEnables = checkRegisterCompatibility(ival); + + // If board enable flags match, change the register set + if (boardEnables == 0) + { + boardsActive = ival; + } + else + { + sprintf(strbuf, " Board enable flags do not match (0x%08x)", boardEnables); + sendSerial(strbuf); + } + } + } + else + { + sprintf(strbuf, " Invalid number of boards (1 - %d)", MAX_BOARDS); + sendSerial(strbuf); + commandError = 1; + } + } + else if (!strcmp(commandString, "STOP")) + { + stopConverter(); + testing = FALSE; + my12 = 0; + } + else if(!strcmp(commandString, "CAL")) + { + if (running == 1) + { + sprintf(strbuf, " Parameters may not be updated while running!"); + sendSerial(strbuf); + commandError = 1; + } + + if (!commandError){ + raw = TRUE; + menuRedraw(NO_PROMPT); + } + } + else if(!strcmp(commandString, "UNCAL")) + { + if (running == 1) + { + sprintf(strbuf, " Parameters may not be updated while running!"); + sendSerial(strbuf); + commandError = 1; + } + + if (!commandError){ + raw = FALSE; + menuRedraw(NO_PROMPT); + } + } + else + { + if (strcmp(commandString, "")) + { + commandError = 1; + } + } + + if (commandError) + { + sendSerial(" !"); + } + + menuPrompt(MENU_DCM1); +} + +/************************************************************ +* Routine: processCommand +* Input: none +* Returns: none +* Description: +* This is the main serial communications routine. Everything +* starts here as soon as a command is avaiable for processing. +**************************************************************/ +void processCommand(void) +{ + if (!serialStatus.command && !serialStatus.repeat) + { + return; + } + + doCommand(); // if not computer (i.e. terminal) you can do the command as well + + bufloc = 0; + rxbuf[bufloc] = 0; + + serialStatus.computer = FALSE; + serialStatus.command = FALSE; +} + +/************************************************************ +* Routine: waitCommand +* Input: none +* Returns: none +* Description: +**************************************************************/ +bool waitCommand(void) +{ + if (!serialStatus.command && !serialStatus.repeat) + { + return TRUE; + } + + serialStatus.computer = FALSE; + serialStatus.command = FALSE; + + return FALSE; +} + +// Verify that the same boards are enabled in both the current register and +// the specified register + +