Treehouse Mbed Team / Mbed 2 deprecated APS_DCM1SL2

Dependencies:   mbed

src/command.cpp

Committer:
mfwic
Date:
2018-12-05
Revision:
7:860b3a8275cb
Parent:
6:39442d493098
Child:
8:d3d7dca419b3

File content as of revision 7:860b3a8275cb:

//-------------------------------------------------------------------------------
// 
//  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 "RTC.h"
#include "parameters.h"
#include "all_io.h"
//#include "calibrate.h"
#include "boards.h"
#include "menu.h"

extern unsigned int boardsActive;
extern unsigned int boardMults;
extern unsigned int binCode[6];
extern unsigned int thermCode[17];
extern 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);
       //if(DEBUG){
       //  sprintf(strbuf, "commandStringBuf= %s, commandData= %d", commandStringBuf, commandData);
       //  sendSerial(strbuf);
       //}
    }
    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: validateChannel
* Input:   channel
* Returns: none
* Description:
* Verifies that the channel number is a valid value between 
* 1 and MAX_BOARDS, setting commandError if the check fails
**************************************************************/
void validateChannel(int channel)
{
   if ((channel < 1) || (channel > MAX_BOARDS))
   {
      sprintf(strbuf, " Invalid channel/board: %d (range is 1 - %d)", channel, MAX_BOARDS);
      sendSerial(strbuf);
      commandError = 1;
   }
}

/************************************************************
* Routine: setPairVariable
* Input:   *avariable,*bvariable
* Returns: none
* Description:
* sets a single channel variable
**************************************************************/
void setPairVariable(float *avariable, float *bvariable, float limitlo, float limithi)
{
   if (!readback)
   {
      if (validateEntry(SET, limitlo, limithi, avariable))
      {
         *bvariable = *avariable;
      }
   }
}


/************************************************************
* Routine: chlprMenu
* Input:   none
* Returns: none
* Description:
* Channel Pair Menu
**************************************************************/
/*void chlprMenu(void)
{
   int ival;
   
   char commandString[80] = { 0 };

   commandError = 0;
   parseCommand(GET, commandString);
 
   if (!strcmp(commandString, "AMPL"))
   {
      if (!readback)
      {
         setPairVariable(&ch[chpair][registerno].a_dwell1_volts, &ch[chpair][registerno].b_dwell1_volts, MIN_VOLTAGE, MAX_VOLTAGE);

         ch[chpair][registerno].a_dwell2_volts = ch[chpair][registerno].a_dwell1_volts;
         ch[chpair][registerno].b_dwell2_volts = ch[chpair][registerno].b_dwell1_volts;
         sprintf(strbuf, " Setting");
         sendSerial(strbuf);
      }

      sprintf(strbuf, " [%d, %d] peak voltage = %0.3f V", chpair, registerno, ch[chpair][registerno].a_dwell1_volts);
      sendSerial(strbuf);
      return;
   }
   
   if (!strcmp(commandString, "DWLPHS"))
   {
      if (!readback)
      {
         // Set dwell times using the specified value
         setPairVariable(&dwells[registerno].a_dwell1_time, &dwells[registerno].b_dwell1_time, MIN_DWELL_TIME_MS, MAX_DWELL_TIME_MS);

         sprintf(strbuf, " Setting");
         sendSerial(strbuf);
      }
      
      sprintf(strbuf, " [%d] in-phase dwell time = %0.3f ms", registerno, dwells[registerno].a_dwell1_time);
      sendSerial(strbuf);
      return;
   }
   
   if (!strcmp(commandString,"DWLPHS_OV"))
   {
      if (!readback)
      {
         setPairVariable(&ch[chpair][registerno].a_dwell1_ov, &ch[chpair][registerno].b_dwell1_ov, MIN_VOLTAGE, MAX_VOLTAGE);

         ch[chpair][registerno].a_dwell2_ov = ch[chpair][registerno].a_dwell1_ov;
         ch[chpair][registerno].b_dwell2_ov = ch[chpair][registerno].b_dwell1_ov;

         sprintf(strbuf, " Setting");
         sendSerial(strbuf);
      }

      sprintf(strbuf, " [%d, %d] in-phase overvoltage = %0.3f V", chpair, registerno, ch[chpair][registerno].a_dwell1_ov);
      sendSerial(strbuf);
      return;
   }
   
   if (!strcmp(commandString,"DWLPHS_OV_TIME"))
   {
      if (!readback)
      {
         // Set overvoltage times using the specified value
         setPairVariable(&dwells[registerno].a_dwell1_ov_time, &dwells[registerno].b_dwell1_ov_time, MIN_DWELL_TIME_MS, MAX_DWELL_TIME_MS);
         dwells[registerno].a_dwell2_ov_time = dwells[registerno].a_dwell1_ov_time;
         dwells[registerno].b_dwell2_ov_time = dwells[registerno].b_dwell1_ov_time;
        
         sprintf(strbuf, " Setting");
         sendSerial(strbuf);
      }

      sprintf(strbuf, " [%d] in-phase overvoltage time = %0.3f ms", registerno, dwells[registerno].a_dwell1_ov_time);
      sendSerial(strbuf);
      return;
   }
   
   if (!strcmp(commandString,"DWLDIFFL"))
   {
      if (!readback)
      {
         // Set dwell times using the specified value
         setPairVariable(&dwells[registerno].a_dwell2_time, &dwells[registerno].b_dwell2_time, MIN_DWELL_TIME_MS, MAX_DWELL_TIME_MS);

         sprintf(strbuf, " Setting");
         sendSerial(strbuf);
      }

      sprintf(strbuf, " [%d] differential dwell time = %0.3f ms", registerno, dwells[registerno].a_dwell2_time);
      sendSerial(strbuf);
      return;
   }
   
   if (!strcmp(commandString, "ENABLE"))
   {
      ival = getival(SET);
      if ((ival != 0) && (ival != 1)) ival = 0;

      if (!readback)
      {
         ch[chpair][registerno].enabled = ival;

         sprintf(strbuf, " Setting");
         sendSerial(strbuf);
      }
      
      sprintf(strbuf, " [%d, %d] enable = %d", chpair, registerno, ch[chpair][registerno].enabled);
      sendSerial(strbuf);
      return;
   }
   
   if (!strcmp(commandString, "DISABLE"))
   {
      if (!readback)
      {
         ch[chpair][registerno].enabled = 0;

         sprintf(strbuf, " Setting");
         sendSerial(strbuf);
      }
      
      sprintf(strbuf, " [%d, %d] enable = %d", chpair, registerno, ch[chpair][registerno].enabled);
      sendSerial(strbuf);
      return;
   }

   if (!strcmp(commandString, "DIFF"))
   {
      ival = getival(SET);
      if ((ival != 0) && (ival != 1)) ival = 0;

      if (!readback)
      {
         ch[chpair][registerno].differential_dwell = ival;

         sprintf(strbuf, " Setting");
         sendSerial(strbuf);
      }
      
      sprintf(strbuf, " [%d, %d] differential_dwell = %d", chpair, registerno, ch[chpair][registerno].differential_dwell);
      sendSerial(strbuf);
      return;
   }
   
   if (!strcmp(commandString, "INVERT"))
   {
      ival = getival(SET);
      if ((ival != 0) && (ival != 1)) ival = 0;

      if (!readback)
      {
         ch[chpair][registerno].inverted = ival;

         sprintf(strbuf, " Setting");
         sendSerial(strbuf);
      }
      
      sprintf(strbuf, " [%d, %d] inverted = %d", chpair, registerno, ch[chpair][registerno].inverted);
      sendSerial(strbuf);
      return;
   }
   
   if (strcmp(commandString, ""))
   {
      commandError = 1;
   }
}*/


/************************************************************
* Routine: setSingleVariable
* Input:   *avariable,*bvariable
* Returns: none
* Description:
* sets a single channel variable
**************************************************************/
/*void setSingleVariable(float* avariable, float* bvariable, float limitlo, float limithi)
{
   float* variable;
   
   if ((chsgl == 'A') || (chsgl == 'a'))
   {
      variable = avariable;
   }
   else
   {
      variable = bvariable;
   }

   if (!readback)
   {
      validateEntry(SET, limitlo, limithi, variable);
   }
}*/


/************************************************************
* Routine: chlsglMenu
* Input:   none
* Returns: none
* Description:
* Channel Single Menu
**************************************************************/
/*void chlsglMenu(void)
{
   int channelSide;
   float value;
   
   char commandString[80] = { 0 };

   commandError = 0;
   parseCommand(GET, commandString);

   channelSide = (((chsgl == 'A') || (chsgl == 'a')) ? 1 : 2);
   
   if (!strcmp(commandString, "DWL1AMPL"))
   {
      if (!readback)
      {
         setSingleVariable(&ch[chpair][registerno].a_dwell1_volts, &ch[chpair][registerno].b_dwell1_volts, MIN_VOLTAGE, MAX_VOLTAGE);

         sprintf(strbuf, " Setting");
         sendSerial(strbuf);
      }

      value = ((channelSide == 1) ? ch[chpair][registerno].a_dwell1_volts : ch[chpair][registerno].b_dwell1_volts);
      
      sprintf(strbuf, " [%d%c, %d] dwell 1 peak amplitude = %0.3f V", chpair, chsgl, registerno, value);
      sendSerial(strbuf);
      return;
   }

   if (!strcmp(commandString, "DWL1"))
   {
      if (!readback)
      {
         // Set dwell times using the specified value
         setSingleVariable(&dwells[registerno].a_dwell1_time, &dwells[registerno].b_dwell1_time, MIN_DWELL_TIME_MS, MAX_DWELL_TIME_MS);

         sprintf(strbuf, " Setting");
         sendSerial(strbuf);
      }
      
      value = ((channelSide == 1) ? dwells[registerno].a_dwell1_time : dwells[registerno].b_dwell1_time);

      sprintf(strbuf, " [%d] dwell 1 time = %0.3f ms", registerno, value);
      sendSerial(strbuf);
      return;
   }

   if (!strcmp(commandString, "DWL1_OV"))
   {
      if (!readback)
      {
         setSingleVariable(&ch[chpair][registerno].a_dwell1_ov, &ch[chpair][registerno].b_dwell1_ov, MIN_VOLTAGE, MAX_VOLTAGE);

         sprintf(strbuf, " Setting");
         sendSerial(strbuf);
      }
      
      value = ((channelSide == 1) ? ch[chpair][registerno].a_dwell1_ov : ch[chpair][registerno].b_dwell1_ov);
      
      sprintf(strbuf, " [%d%c, %d] dwell 1 overvoltage = %0.3f V", chpair, chsgl, registerno, value);
      sendSerial(strbuf);
      return;
   }
   
   if (!strcmp(commandString, "DWL1_OV_TIME"))
   {
      if (!readback)
      {
         // Set channel 1's dwell 1 overvoltage time
         setSingleVariable(&dwells[registerno].a_dwell1_ov_time, &dwells[registerno].b_dwell1_ov_time, MIN_DWELL_TIME_MS, MAX_DWELL_TIME_MS);
         
         sprintf(strbuf, " Setting");
         sendSerial(strbuf);
      }

      value = ((channelSide == 1) ? dwells[registerno].a_dwell1_ov_time : dwells[registerno].b_dwell1_ov_time);

      sprintf(strbuf, " [%d] dwell 1 overvoltage time = %0.3f ms", registerno, value);
      sendSerial(strbuf);
      return;
   }

   if (!strcmp(commandString, "DWL2AMPL"))
   {
      if (!readback)
      {
         setSingleVariable(&ch[chpair][registerno].a_dwell2_volts, &ch[chpair][registerno].b_dwell2_volts, MIN_VOLTAGE, MAX_VOLTAGE);

         sprintf(strbuf, " Setting");
         sendSerial(strbuf);
      }

      value = ((channelSide == 1) ? ch[chpair][registerno].a_dwell2_volts : ch[chpair][registerno].b_dwell2_volts);
      
      sprintf(strbuf, " [%d%c, %d] dwell 2 peak amplitude = %0.3f V", chpair, chsgl, registerno, value);
      sendSerial(strbuf);
      return;
   }
   
   if (!strcmp(commandString,"DWL2"))
   {
      if (!readback)
      {
         // Set dwell 2 time
         setSingleVariable(&dwells[registerno].a_dwell2_time, &dwells[registerno].b_dwell2_time, MIN_DWELL_TIME_MS, MAX_DWELL_TIME_MS);
         
         sprintf(strbuf, " Setting");
         sendSerial(strbuf);
      }
      
      value = ((channelSide == 1) ? dwells[registerno].a_dwell2_time : dwells[registerno].b_dwell2_time);

      sprintf(strbuf, " [%d] dwell 2 time = %0.3f ms", registerno, value);
      sendSerial(strbuf);
      return;
   }
   
   if (!strcmp(commandString, "DWL2_OV"))
   {
      if (!readback)
      {
         setSingleVariable(&ch[chpair][registerno].a_dwell2_ov, &ch[chpair][registerno].b_dwell2_ov, MIN_VOLTAGE, MAX_VOLTAGE);

         sprintf(strbuf, " Setting");
         sendSerial(strbuf);
      }
      
      value = ((channelSide == 1) ? ch[chpair][registerno].a_dwell2_ov : ch[chpair][registerno].b_dwell2_ov);
      
      sprintf(strbuf, " [%d%c, %d] dwell 2 overvoltage = %0.3f V", chpair, chsgl, registerno, value);
      sendSerial(strbuf);
      return;
   }

   if (!strcmp(commandString, "DWL2_OV_TIME"))
   {
      if (!readback)
      {
         // Set dwell 2 overvoltage time
         setSingleVariable(&dwells[registerno].a_dwell2_ov_time, &dwells[registerno].b_dwell2_ov_time, MIN_DWELL_TIME_MS, MAX_DWELL_TIME_MS);
         
         sprintf(strbuf, " Setting");
         sendSerial(strbuf);
      }

      value = ((channelSide == 1) ? dwells[registerno].a_dwell2_ov_time : dwells[registerno].b_dwell2_ov_time);

      sprintf(strbuf, " [%d] dwell 2 overvoltage time = %0.3f ms", registerno, value);
      sendSerial(strbuf);
      return;
   }
   
   if (!strcmp(commandString, "ENABLE"))
   {
      if (!readback)
      {
         ch[chpair][registerno].enabled = 1;

         sprintf(strbuf, " Setting");
         sendSerial(strbuf);
      }
      
      sprintf(strbuf, " [%d, %d] enable = %d", chpair, registerno, ch[chpair][registerno].enabled);
      sendSerial(strbuf);
      return;
   }

   if (!strcmp(commandString,"DISABLE"))
   {
      if (!readback)
      {
         ch[chpair][registerno].enabled = 0;

         sprintf(strbuf, " Setting");
         sendSerial(strbuf);
      }
      
      sprintf(strbuf, " [%d, %d] enable = %d", chpair, registerno, ch[chpair][registerno].enabled);
      sendSerial(strbuf);
      return;
   }

   if (strcmp(commandString, ""))
   {
      commandError = 1;
   }
}*/


/************************************************************
* Routine: testMenu
* Input:   none
* Returns: none
* Description:
* testMenu
**************************************************************/
void testMenu(void)
{
   int ival;
   int ch, dac;
   //float fval;
   unsigned int data;

   char commandString[80] = { 0 };
   

   commandError = 0;
   parseCommand(GET, commandString);
 
   if (!strcmp(commandString, "LEDS")) // duh do I have to tell you?
   {
      //testLEDs();
      return;
   }
   
   if (!strcmp(commandString, "SELFTEST"))
   {
      if ((rxbuf[bufloc] == 0x0D) || (rxbuf[bufloc] == 0))
      {
         //ival = DEFAULT_SELFTEST_BOARDS;
         ival = 0;
      }
      else
      {
         ival = getival(SET);

         if ((ival < 1) || (ival > MAX_BOARDS))
         {
            sprintf(strbuf, " Invalid number of channels/boards (range is 1 - %d)", MAX_BOARDS);
            sendSerial(strbuf);
            commandError = 1;
            return;
         }
      }
      
      //selfTest(ival);
      return;
   }
      
   if (!strcmp(commandString, "HVEN")) // high voltage enable
   {
      ival = getival(SET);
      //hv_en = ival;
      return;
   }

   if (!strcmp(commandString, "DAC"))
   {
      ch = getival(SET);
      getDelimiter();
      dac = getival(SET);
      getDelimiter();
      data = getival(SET);

      validateChannel(ch);
      if (commandError) return;
      ch--;
      
      //sendData((unsigned int)ch, (unsigned int)dac, data);
      sprintf(strbuf, " ch: %u dac: %u value: %u", ch + 1, dac, data);
      sendSerial(strbuf);
      return;
   }
   
   if (!strcmp(commandString, "DINIT"))
   {
      //initDACs();
      return;
   }

   if (!strcmp(commandString, "FINIT"))
   {
      //formatParameterSector();
      return;
   }

   if (!strcmp(commandString, "CINIT"))
   {
      //initCalParameters();
      sprintf(strbuf, " All calibration parameters set to default values");
      sendSerial(strbuf);
      return;
   }
/*
   if (!strcmp(commandString, "VOLTS"))
   {
      ch = getival(SET);
      getDelimiter();
      dac = getival(SET);
      getDelimiter();
      fval = getfval(SET);

      validateChannel(ch);
      if (commandError) return;
      ch--;
      
      if (dac == 1)
      {
         data = (unsigned int)(cal[ch].a_scale  *  fval + cal[ch].a_offset);
         dac  = ADC_CH1;
      }
      else
      {
         data = (unsigned int)(cal[ch].b_scale  *  fval + cal[ch].b_offset);
         dac  = ADC_CH2;
      }
  
      sendData((unsigned int)ch, (unsigned int)dac, data);
      sprintf(strbuf, " ch: %u dac: %u value: %u", ch + 1, dac, data);
      sendSerial(strbuf);
      return;
   }

   if (!strcmp(commandString, "BENB")) // board enable bits
   {
      ival = getival(SET);
      setBoardEnables((unsigned int)ival);
      sprintf(strbuf, " Board Enable Bits = 0x%04x\r\n", ival); 
      sendSerial(strbuf);
      return;
   }

   if (!strcmp(commandString, "BEN")) // board enable
   {
      ch = getival(SET);
      getDelimiter();
      ival = getival(SET);

      validateChannel(ch);
      if (commandError) return;
      ch--;
      
      setBoardEnable(ch, (unsigned int)ival);
      sprintf(strbuf, " Board Enable %d = %d\r\n", ch + 1, ival); 
      sendSerial(strbuf);
      return;
   }

   if (!strcmp(commandString, "LD"))
   {
      ival = getival(SET);

      if (ival)
      {
         tst_ld = 1;
      }
      else
      {
         tst_ld = 0;
      }

      Delay(100);
      ival = dtst_out;
      sprintf(strbuf, " DTST_OUT = %d\r\n", ival); 
      sendSerial(strbuf);
      return;
   }

   if (!strcmp(commandString, "SCK"))
   {
      ival = getival(SET);

      if (ival)
      {
         sclk = 1;
      }
      else
      {
         sclk = 0;
      }

      ival = dtst_out;
      sprintf(strbuf, " DTST_OUT = %d\r\n", ival); 
      sendSerial(strbuf);
      return;
   }
   
   if (!strcmp(commandString, "FLASHDEMO")) // flash test
   {
      flashdemo();
      return;
   }

   if (!strcmp(commandString, "HVGOOD"))
   {
      sprintf(strbuf, " HVCMP1: %i HVCMP2: %i", (int)hv_cmptr1, (int)hv_cmptr2);
      sendSerial(strbuf);
      return;
   }
*/
   if (strcmp(commandString, ""))
   {
      commandError = 1;
   }
}

/************************************************************
* Routine: setDwellTime
* Input:   dwellType (enum)
* Returns: none
* Description:
* Set the specified dwell time in [registerno] to the indicated 
* number of milliseconds
**************************************************************/
/*enum { DWELL_1_OV_TIME,  DWELL_1_TIME,  DWELL_2_OV_TIME,  DWELL_2_TIME };

void setDwellTime(int dwellType)
{
   char channelSideChar, setSingleChannel;
   float fValue;

   if (readback)
   {
      if (dwellType == DWELL_1_OV_TIME)
      {
         sprintf(strbuf, "\r\n Channel A Dwell 1 OV Time [%i] = %0.3f", registerno + 1, dwells[registerno].a_dwell1_ov_time);
         sendSerial(strbuf);
         sprintf(strbuf, "\r\n Channel B Dwell 1 OV Time [%i] = %0.3f", registerno + 1, dwells[registerno].b_dwell1_ov_time);
         sendSerial(strbuf);
      }

   }
   else if (running == 1)
   {
      sprintf(strbuf, " Parameters may not be updated while running!");
      sendSerial(strbuf);
   }
   else 
   {
      // Find the next command string character
      while (rxbuf[bufloc] == ' ' || rxbuf[bufloc] == '[' && rxbuf[bufloc] != 0x0D ){ bufloc++; }

      // Is the user setting a single channel or a channel pair?
      channelSideChar  = toupper(rxbuf[bufloc]);
      setSingleChannel = ((channelSideChar == 'A') || (channelSideChar == 'B'));

      if (setSingleChannel) 
      {
         chsgl = channelSideChar;
         
         // Skip over the channel side character
         bufloc++;

         // Find the next command string character
         while (rxbuf[bufloc] == ' ' || rxbuf[bufloc] == ',' && rxbuf[bufloc] != 0x0D ){ bufloc++; }
      }

      // Back up because the current character should be the start of the register 
      // number but validateInt() is going to advance one character before calling
      // atof()
      bufloc--;

      if (!validateInt(SET, 1, MAX_REGISTERS, &registerno))
      {
         sprintf(strbuf, " Invalid register number (1 - %d)", MAX_REGISTERS);
         sendSerial(strbuf);
         commandError = 1;
      }

      if (!commandError)
      {
         // Adjust user values (1 - MAX) to 0 offset values (0 - (MAX - 1))
         registerno--;

         // Skip over the register number
         while (isdigit(rxbuf[bufloc]) && rxbuf[bufloc] != 0x0D ){ bufloc++; }

         // Skip over white space and delimiters
         while (rxbuf[bufloc] == ' ' || rxbuf[bufloc] == ',' && rxbuf[bufloc] != 0x0D ){ bufloc++; }

         // Back up because the current character should be the start of the value
         // but validateEntry() is going to advance one character before calling
         // atof()
         bufloc--;

         // Read and validate the dwell time value
         if (!validateEntry(SET, MIN_DWELL_TIME_MS, MAX_DWELL_TIME_MS, &fValue))
         {
            sprintf(strbuf, " Invalid dwell time");
            sendSerial(strbuf);
            commandError = 1;
         }
      }

      if (!commandError)
      {
         if (dwellType == DWELL_1_OV_TIME)
         {
            if ((!setSingleChannel) || (channelSideChar == 'A'))
            {
               dwells[registerno].a_dwell1_ov_time = fValue;
               sprintf(strbuf, "\r\n Channel A Dwell 1 OV Time [%i] = %0.3f", registerno + 1, dwells[registerno].a_dwell1_ov_time);
               sendSerial(strbuf);
            }
            if ((!setSingleChannel) || (channelSideChar == 'B'))
            {
               dwells[registerno].b_dwell1_ov_time = fValue;
               sprintf(strbuf, "\r\n Channel B Dwell 1 OV Time [%i] = %0.3f", registerno + 1, dwells[registerno].b_dwell1_ov_time);
               sendSerial(strbuf);
            }
         }
         
      }
   }
}*/


// Clear the specified register
/*
void clearRegister(unsigned int reg)
{
   int i;
   
   dwells[reg].a_dwell1_time    = 0;
   dwells[reg].a_dwell2_time    = 0;
   dwells[reg].a_dwell1_ov_time = 0;
   dwells[reg].a_dwell2_ov_time = 0;
   dwells[reg].b_dwell1_time    = 0;
   dwells[reg].b_dwell2_time    = 0;
   dwells[reg].b_dwell1_ov_time = 0;
   dwells[reg].b_dwell2_ov_time = 0;
   
   for (i = 0; i < MAX_BOARDS; i++)
   {
      ch[i][reg].enabled            = 0;
      ch[i][reg].installed          = 0;
      ch[i][reg].inverted           = 0;
      ch[i][reg].differential_dwell = 1;

      ch[i][reg].a_dwell1_volts = 0;
      ch[i][reg].a_dwell2_volts = 0;
      ch[i][reg].a_dwell1_ov    = 0;
      ch[i][reg].a_dwell2_ov    = 0;
      ch[i][reg].b_dwell1_volts = 0;
      ch[i][reg].b_dwell2_volts = 0;
      ch[i][reg].b_dwell1_ov    = 0;
      ch[i][reg].b_dwell2_ov    = 0;
   }
}*/
    

/************************************************************
* Routine: doCommand
* Input:   none
* Returns: none
* Description:
* This is the start of the command string.
**************************************************************/
void doCommand(void)
{
   //int channelNum, channelSide, numPoints, i; 
   int ival;
   //char channelSideChar;
   unsigned int boardEnables;

   char commandString[80] = { 0 };

   bufloc = 0;
   commandError = 0;

   parseCommand(GET, commandString);

   if (!strcmp(commandString, "MENU"))
   {
      menuRedraw();//RK: menuRedraw is empty.
   }
   else if (!strcmp(commandString, "HELP"))
   {
      menuRedraw();//RK: menuRedraw is empty.
   }
   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]
   {
      
      boardsActive = commandData;
      
      if (readback)
      {
         sprintf(strbuf, " %d", boardsActive);
         sendSerial(strbuf);
      }
      //else if (running == 1)
      //{
      //   sprintf(strbuf, " Parameters may not be updated while running!");
      //   sendSerial(strbuf);
      //}
      else
      {
         if(checkRange(boardsActive, 0, 63) == 1){
            en_out_code = setBoardWeights(boardsActive);
         }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}
   {
      boardMults = commandData;
      
      if (readback)
      {
         sprintf(strbuf, " %d", boardMults);
         sendSerial(strbuf);
      }
      //else if (running == 1)
      //{
      //   sprintf(strbuf, " Parameters may not be updated while running!");
      //   sendSerial(strbuf);
      //}
      else
      {
         if(checkRange(boardMults, 0, 63) == 1){
            en_out_code = setBoardWeights(boardMults);
         }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}
   {
      my12 = commandData;
      
      //if(DEBUG){
      //  sprintf(strbuf, "my12=%d commandData=%d\r\n", my12, commandData);
      //  sendSerial(strbuf);
      //}
      
      if (readback)
      {
         sprintf(strbuf, " %d", my12);
         sendSerial(strbuf);
      }
   }
   else if (!strcmp(commandString, "ALLOFF"))
   {
      
      //hv_en = 1;
      //wr_out_code = setBoardEnables((unsigned int)ALLOFF);
      my12 = 0;
      running = FALSE;
      //setBoardEnables((unsigned int *)alloff);
      if(DEBUG){
        sprintf(strbuf, "wr_out_code=%d\r\n", wr_out_code);
        sendSerial(strbuf);
      }
   }
   else if (!strcmp(commandString, "ALLON"))
   {
      //hv_en = 0;
      //setBoardEnables((unsigned int *)allon);
      wr_out_code = setBoardEnables((unsigned int)ALLON);
   }
   else if (!strcmp(commandString, "DWL1_OV_TIME"))
   {
       //setDwellTime(DWELL_1_OV_TIME);
   }
   else if (!strcmp(commandString, "DWL1_TIME"))
   {
       //setDwellTime(DWELL_1_TIME);
   }
   else if (!strcmp(commandString, "RUN"))
   {
      // Skip over any white space and the optional '[' character
      while ((isspace(rxbuf[bufloc])) || (rxbuf[bufloc] == '[')) bufloc++;
      
      if (rxbuf[bufloc] == '0')
      {
         stopConverter();
         //setDacsToZeroVolts();
      }
      else if ((rxbuf[bufloc] > '0') && (rxbuf[bufloc] < '0' + MAX_BOARDS))
      {
         ival = atoi(&rxbuf[bufloc]);
         ival--;
         
         if (running == 0)
         {
            //setDacsToZeroVolts();
            //Delay(1000);
            wait(0.5);
            boardsActive = ival;
            startConverter(boardsActive);
         }
         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 register number (1 - %d)", MAX_BOARDS);
         sendSerial(strbuf);
         commandError = 1;
      }
   }
   else if (!strcmp(commandString, "STOP"))
   {
      stopConverter();
      //hv_en = OFF;
   }
/*   else if (!strcmp(commandString, "CLEAR"))
   {
      if (running == 1)
      {
         sprintf(strbuf, " Parameters may not be updated while running!");
         sendSerial(strbuf);
         commandError = 1;
      }
      else if (!validateInt(SET, 0, MAX_REGISTERS, &registerno))
      {
         sprintf(strbuf, " Invalid register number (1 - %d)", MAX_REGISTERS);
         sendSerial(strbuf);
         commandError = 1;
      }
      
      if (!commandError)
      {
         if (registerno == 0)
         {
            frequency = 1000;
            
            clearRegister(0);
            clearRegister(1);
            clearRegister(2);
            clearRegister(3);

            initCalParameters();
            
            sprintf(strbuf, " All parameters reset to default values");
            sendSerial(strbuf);
         }
         else
         {
            // Adjust user values (1 - MAX) to 0 offset values (0 - (MAX - 1))
            registerno--;

            clearRegister(registerno);
            
            sprintf(strbuf, " [x, %d] voltages are 0", registerno);
            sendSerial(strbuf);
         }
      }
   }*/
   else if(!strcmp(commandString, "TEST"))
   {
      if (running == 1)
      {
         sprintf(strbuf, " Parameters may not be updated while running!");
         sendSerial(strbuf);
      }
      else
      {
         testMenu();
      }
   }
/*   else if(!strcmp(commandString, "READ"))
   {
      if (!validateInt(SET, 1, MAX_REGISTERS, &registerno))
      {
         sprintf(strbuf, " Invalid register number (1 - %d)", MAX_REGISTERS);
         sendSerial(strbuf);
         commandError = 1;
      }

      if (!commandError)
      {
         // Adjust user values (1 - MAX) to 0 offset values (0 - (MAX - 1))
         registerno--;
         
         sprintf(strbuf, "\r\n Register [x, %d]: ", registerno + 1);
         sendSerial(strbuf);
         sprintf(strbuf, "\r\n         frequency = %0.3f Hz", frequency);
         sendSerial(strbuf);
         sprintf(strbuf, "\r\n    dwell1_ov_time = %0.3f ms", dwells[registerno].a_dwell1_ov_time);
         sendSerial(strbuf);
         sprintf(strbuf, "\r\n       dwell1_time = %0.3f ms", dwells[registerno].a_dwell1_time);
         sendSerial(strbuf);

         for (i = 0; i < MAX_BOARDS; i++)
         {
            sprintf(strbuf, "\r\n\r\n Register [%d, %d]: ", i + 1, registerno + 1);
            sendSerial(strbuf);
            sprintf(strbuf, "\r\n             enabled = %d", ch[i][registerno].enabled);
            sendSerial(strbuf);
            sprintf(strbuf, "\r\n         a_dwell1_ov = %0.3f V", ch[i][registerno].a_dwell1_ov);
            sendSerial(strbuf);
            sprintf(strbuf, "\r\n      a_dwell1_volts = %0.3f V", ch[i][registerno].a_dwell1_volts);
            sendSerial(strbuf);

         }
      }
   }*/
/*   else if(!strcmp(commandString, "CAL"))
   {
      if (running == 1)
      {
         sprintf(strbuf, " Parameters may not be updated while running!");
         sendSerial(strbuf);
         commandError = 1;
      }
      else if (!validateInt(SET, 1, MAX_BOARDS, &channelNum))
      {
         sprintf(strbuf, " Invalid board number (1 - %d)", MAX_BOARDS);
         sendSerial(strbuf);
         commandError = 1;
      }

      if (!commandError)
      {
         // Adjust user values (1 - MAX) to 0 offset values (0 - (MAX - 1))
         channelNum--;
         
         // Skip over digits parsed as part of the atoi() call
         while (isdigit(rxbuf[bufloc])) bufloc++;

         // Does the user simply want to read the current cal parameters?         
         if (rxbuf[bufloc] == '?')
         {
            sprintf(strbuf, "\r\nChannel %dA Scale = %0.4f Offset = %0.4f", channelNum, cal[channelNum].a_scale, cal[channelNum].a_offset);
            sendSerial(strbuf);
            sprintf(strbuf, "\r\nChannel %dB Scale = %0.4f Offset = %0.4f", channelNum, cal[channelNum].b_scale, cal[channelNum].b_offset);
            sendSerial(strbuf);
            sendCRLF();
            return;
         }

         // First character after digits must be either 'A' or 'B'
         channelSideChar = toupper(rxbuf[bufloc]);
         
         if ((channelSideChar != 'A') && (channelSideChar != 'B'))
         {
            sprintf(strbuf, " Invalid channel (A/B)");
            sendSerial(strbuf);
            commandError = 1;
         }
      }

      if (!commandError)
      {
         // Translate 'A' to CHAN1 and 'B' to CHAN2
         channelSide = (channelSideChar == 'A' ? 1 : 2);
         
         // Move past the channel side character
         bufloc++;

         // Does the user simply want to read the current cal parameters?
         if (rxbuf[bufloc] == '?')
         {
            if (channelSide == 1)
            {
               sprintf(strbuf, "\r\nChannel %dA Scale = %0.4f Offset = %0.4f", channelNum, cal[channelNum].a_scale, cal[channelNum].a_offset);
               sendSerial(strbuf);
            }
            else
            {
               sprintf(strbuf, "\r\nChannel %dB Scale = %0.4f Offset = %0.4f", channelNum, cal[channelNum].b_scale, cal[channelNum].b_offset);
               sendSerial(strbuf);
            }

            sendCRLF();
            return;
         }

         // If no point value specified, silently default to 3-point cal
         if (!strcmp(&rxbuf[bufloc], ""))
         {
            numPoints = 3;
         }
         else if (!validateInt(SET, 3, 11, &numPoints))
         {
            sprintf(strbuf, " Invalid number of cal points (3 - 11)");
            sendSerial(strbuf);
            commandError = 1;
         }
      }
       
      if (!commandError)
      {
         sprintf(strbuf, " Starting %d-point Calibration on Channel %d%c", numPoints, channelNum, channelSideChar);
         sendSerial(strbuf);
         
         // Reset the serial buffer for the incoming user input
         bufloc = 0;
         rxbuf[bufloc] = 0;
         
         calibrate(channelNum, channelSide, numPoints);
      }
   }
   else if (!strcmp(commandString, "COMMIT"))
   {
      commitParametersToFlash();
   }
   else if (!strcmp(commandString, "CHLPR"))
   {
      if (readback)
      {
         sprintf(strbuf, " [%i, %i]", chpair, registerno);
         sendSerial(strbuf);
      }
      else if (running == 1)
      {
         sprintf(strbuf, " Parameters may not be updated while running!");
         sendSerial(strbuf);
      }
      else 
      {
         if (!validateInt(SET, 1, MAX_BOARDS, &chpair))
         {
            sprintf(strbuf, "Invalid board number (1 - %d)", MAX_BOARDS);
            sendSerial(strbuf);
            commandError = 1;
         }
         
         if (!commandError)
         {
            getDelimiter();

            if (!validateInt(SET, 1, MAX_REGISTERS, &registerno))
            {
               sprintf(strbuf, "Invalid register number (1 - %d)", MAX_REGISTERS);
               sendSerial(strbuf);
               commandError = 1;
            }
         }

         if (!commandError)
         {
            // Adjust user values (1 - MAX) to 0 offset values (0 - (MAX - 1))
            chpair--;
            registerno--;
            
            // ignore spaces
            while ((rxbuf[bufloc++] == ' ') && (rxbuf[bufloc] != 0x0D) && (rxbuf[bufloc] != 0) && (rxbuf[bufloc] != ';'));
            
            if (rxbuf[bufloc] == 0 || rxbuf[bufloc] == 0x0D)
            {
               commandError = 1;
            }
            else
            {
               while((rxbuf[bufloc++] != ' ') && (rxbuf[bufloc] != 0x0D) && (rxbuf[bufloc] != 0) && (rxbuf[bufloc] == ';') );
            
               if (rxbuf[bufloc] == 0 || rxbuf[bufloc] == 0x0D)
               {
                  commandError = 1;
               }
               else
               {       
                  chlprMenu();
               }
            }
         }
      }
   }
   else if (!strcmp(commandString, "CHLSGL"))
   {
      if (readback)
      {
         sprintf(strbuf, " [%i%c, %i]", chpair, chsgl, registerno);
         sendSerial(strbuf);
      }
      else if (running == 1)
      {
         sprintf(strbuf, " Parameters may not be updated while running!");
         sendSerial(strbuf);
      }
      else 
      {
         if (!validateInt(SET, 1, MAX_BOARDS, &chpair))
         {
            sprintf(strbuf, "Invalid board number (1 - %d)", MAX_BOARDS);
            sendSerial(strbuf);
            commandError = 1;
         }

         if (!commandError)
         {
            while(rxbuf[bufloc] == ' ' || rxbuf[bufloc] == '[' || isdigit(rxbuf[bufloc]) && rxbuf[bufloc] != 0x0D ){ bufloc++; }
            
            channelSideChar = toupper(rxbuf[bufloc]);
            
            if ((channelSideChar != 'A') && (channelSideChar != 'B'))
            {
               sprintf(strbuf, "Invalid channel (A/B)");
               sendSerial(strbuf);
               commandError = 1;
            }
            
            if (!commandError)
            {
               chsgl = channelSideChar;
               getDelimiter();

               if (!validateInt(SET, 1,  MAX_REGISTERS, &registerno))
               {
                  sprintf(strbuf, "Invalid register number (1 - %d)", MAX_REGISTERS);
                  sendSerial(strbuf);
                  commandError = 1;
               }
            }
            
            if (!commandError)
            {
               // Adjust user values (1 - MAX) to 0 offset values (0 - (MAX - 1))
               chpair--;
               registerno--;
            
               // ignore spaces
               while ((rxbuf[bufloc++] == ' ') && (rxbuf[bufloc] != 0x0D) && (rxbuf[bufloc] != 0) && (rxbuf[bufloc] == ';'));
         
               if (rxbuf[bufloc] == 0 || rxbuf[bufloc] == 0x0D)
               {
                  commandError = 1;
               }
            }

            if (!commandError)
            {
               while ((rxbuf[bufloc++] != ' ') && (rxbuf[bufloc] != 0x0D) && (rxbuf[bufloc] != 0) && (rxbuf[bufloc] == ';'));
            
               if (rxbuf[bufloc] == 0 || rxbuf[bufloc] == 0x0D)
               {
                  commandError = 1;
               }
               else       
               {
                  chlsglMenu();
               }
            }
         }
      }
   }*/
   else 
   { 
      if (strcmp(commandString, ""))
      {
         commandError = 1;
      }
   }

   if (commandError)
   {
      sendSerial(" !");
   }

   //sendCRLF();
   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;
}