Treehouse Mbed Team / Mbed 2 deprecated APS_DCM1SL2

Dependencies:   mbed

src/command.cpp

Committer:
Slord2142
Date:
2019-08-22
Revision:
34:419242dc004d
Parent:
33:6c7364ea360f
Child:
35:ec224d706f7c

File content as of revision 34:419242dc004d:

//-------------------------------------------------------------------------------
// 
//  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"
#include "SOFBlock.h"
#include "adc.h"

uint8_t *storo;
char storoBuild[200], storoFrag[10];
char storoSpace[2] = ":";
unsigned int boardsActive = ALLON;
unsigned int boardMults = 32;
double commandData;
unsigned int section;
unsigned int fort;
unsigned int select;
double VOLTAGE_48_ACTUAL_VALUE = 1.51;
double VOLTAGE_24_ACTUAL_VALUE = 1.55;
double VOLTAGE_12_ACTUAL_VALUE = 1.65;
double VOLTAGE_48_OFFSET = 0;
double VOLTAGE_24_OFFSET = 0;
double VOLTAGE_12_OFFSET = 0;
int Vloc = 0;
int Aloc = 0;
double VOLTAGE_CAL_1;
double VOLTAGE_CAL_2;
double VOLTAGE_CAL_3;
double VSTORE_1;
double VSTORE_2;
double VSTORE_3;
struct adcValues adcVals;
struct displayValues dvals;
signed int CURRENT_48_DIV_FACTOR5 = -370;
signed int CURRENT_48_DIV_FACTOR4 = -570;
signed int CURRENT_48_DIV_FACTOR3 = -740;
signed int CURRENT_48_DIV_FACTOR2 = -948;
signed int CURRENT_48_DIV_FACTOR1 = -1541;
signed int CURRENT_48_DIV_FACTOR0 = -1610;

unsigned int CURRENT_48_DIV_THRESH5 = 3000;
unsigned int CURRENT_48_DIV_THRESH4 = 2500;
unsigned int CURRENT_48_DIV_THRESH3 = 2000;
unsigned int CURRENT_48_DIV_THRESH2 = 1500;
unsigned int CURRENT_48_DIV_THRESH1 = 500;

signed int CURRENT_24_DIV_FACTOR = -376;

signed int CURRENT_12_DIV_FACTOR5 = -188;
signed int CURRENT_12_DIV_FACTOR4 = -186;
signed int CURRENT_12_DIV_FACTOR3 = -182;
signed int CURRENT_12_DIV_FACTOR2 = -177;
signed int CURRENT_12_DIV_FACTOR1 = -179;
signed int CURRENT_12_DIV_FACTOR0 = -175;

unsigned int CURRENT_12_DIV_THRESH5 = 1600;
unsigned int CURRENT_12_DIV_THRESH4 = 800;
unsigned int CURRENT_12_DIV_THRESH3 = 600;
unsigned int CURRENT_12_DIV_THRESH2 = 400;
unsigned int CURRENT_12_DIV_THRESH1 = 200;

unsigned int CURRENT_REF_1;
unsigned int CURRENT_REF_2;
unsigned int CURRENT_REF_3;
unsigned int CURRENT_REF_4;
unsigned int CURRENT_REF_5;
unsigned int CURRENT_REF_6;
double CURRENT_IN_1;
double CURRENT_IN_2;
double CURRENT_IN_3;
double CURRENT_IN_4;
double CURRENT_IN_5;
double CURRENT_IN_6;

double CURRENT_12_CORRECTION0;
double CURRENT_12_CORRECTION1;
double CURRENT_12_CORRECTION2;
double CURRENT_12_CORRECTION3;
double CURRENT_12_CORRECTION4;
double CURRENT_12_CORRECTION5;
extern unsigned short my12;
char storage[50];

/************* TEMPORARY WRITING BLOCK *********************/

SOFWriter writer;
SOFReader reader;

/************* 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 = atof(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, "PERM"))
   {
      if (readback)
      {
         reader.open(sector_index);
         //printf("data %d bytes at %p :\r\n", reader.get_data_size(), reader.get_physical_data_addr());
         //printf("%.*s\r\n", reader.get_data_size(), reader.get_physical_data_addr());
         storo = reader.get_physical_data_addr();
         reader.close();
         printf("%s\r\n", storo);
         sprintf(storage, "%s", storo);
         int storage_size = strlen(storage);
         char delim[] = ":";
         char *ptr = strtok(storage, delim);
         if (ptr != NULL)
         {
            CURRENT_48_DIV_FACTOR0 = atoi(ptr);
            ptr = strtok(NULL, delim);
            if (ptr != NULL)
            {
                CURRENT_48_DIV_FACTOR1 = atoi(ptr);
                ptr = strtok(NULL, delim);
                if (ptr != NULL)
                {
                    CURRENT_48_DIV_FACTOR2 = atoi(ptr);
                    ptr = strtok(NULL, delim);
                    if (ptr != NULL)
                    {
                        CURRENT_48_DIV_FACTOR3 = atoi(ptr);
                        ptr = strtok(NULL, delim);
                        if (ptr != NULL)
                        {
                            CURRENT_48_DIV_FACTOR4 = atoi(ptr);
                            ptr = strtok(NULL, delim);
                            if (ptr != NULL)
                            {
                                CURRENT_48_DIV_FACTOR5 = atoi(ptr);
                                printf("%d\r\n", CURRENT_48_DIV_FACTOR0);
                                printf("%d\r\n", CURRENT_48_DIV_FACTOR1);
                                printf("%d\r\n", CURRENT_48_DIV_FACTOR2);
                                printf("%d\r\n", CURRENT_48_DIV_FACTOR3);
                                printf("%d\r\n", CURRENT_48_DIV_FACTOR4);
                                printf("%d\r\n", CURRENT_48_DIV_FACTOR5);
                            } else {
                                printf("Insufficient variables found.");
                            }
                        } else {
                            printf("Infussicient variables found.");
                        }
                    } else {
                        printf("Insufficient variables found.");
                    }
                } else {
                    printf("Insufficient variables found.");
                }
            } else {
                printf("Insufficient variables found.");
            }
         } else {
            printf("Infufficient variables found.");
         }
         sendSerial(strbuf);
         
      }
      else if (running == 1)
      {
         sprintf(strbuf, " Parameters may not be updated while running!");
         sendSerial(strbuf);
      }
      else
      {
         if(checkRange(boardMults, 0, 63) == 1){
            writer.open(sector_index) ;
            writer.write_data((uint8_t*) storoBuild, sizeof storoBuild);
            writer.close();
            testing = TRUE;
         }else{
            showRangeError(1, boardMults, 0.0);
         }
      }
   }
   else if (!strcmp(commandString, "PREP"))
   {
      if (readback)
      {
         printf("%s\r\n", storo);
         sendSerial(strbuf);
      }
      else
      {
         if (commandData == 0)
         {
             memset(storoBuild, 0, sizeof storoBuild);
         }
         else
         {
            sprintf(storoFrag, "%d", commandData);
            strcat(storoBuild, storoFrag);
            strcat(storoBuild, storoSpace);
            if(checkRange(boardMults, 0, 63) == 1){
                printf("%s\r\n", storoBuild);
                testing = TRUE;
            }else{
                showRangeError(1, boardMults, 0.0);
            }
         }
      }
    }*/
    else if (!strcmp(commandString, "SECT"))
    {
        if (commandData == 48)
        {
            section = 48;
        }
        else if (commandData == 24)
        {
            section = 24;
            fort = 0;
        }
        else if (commandData == 12)
        {
            section = 12;
        }
        else {
            printf("Input not accepted.");
        }
    }/*
    else if (!strcmp(commandString, "FORT"))
    {
        if (readback)
        {
            if (fort == 0)
            {
                printf("Currently accessing: Div Factors \r\n");
            }
            else if (fort == 1)
            {
                printf("Currently accessing: Div Thresholds \r\n");
            } else {
                printf("Currently accessing: Nothing \r\n");
            }
        }else if (section != 24){
            if (commandData == 0)
            {
                fort = 0;
                printf("Now accessing: Div Factors \r\n");
            }
            else if (commandData == 1)
            {
                fort = 1;
                printf("Now accessing: Div Thresholds \r\n");
            }
        }
    }*/
    else if (!strcmp(commandString, "DIAL"))
    {
        if (Vloc == 0)
        {
            if (section == 48)
            {
                printf("Begin Voltage 48 calibration? (Enter Dial=1 to continue)");
                Vloc = -1;
            }
            else if (section == 24)
            {
                printf("Begin Voltage 24 calibration? (Enter Dial=1 to continue)");
                Vloc = 7;
            }
            else if (section == 12)
            {
                printf("Begin Voltage 12 calibration? (Enter Dial=1 to continue)");
                Vloc = 1;
            }
        }
        else if (Vloc == 1)
        {
            if (commandData == 1)
            {
                printf("Enter actual output at 12V load. (ex. Dial=1.52)");
                Vloc = 2;
            } else{
                printf("Calibration cancelled.");
                Vloc = 0;
            }
        }
        else if (Vloc == 2)
        {
            VOLTAGE_CAL_1 = commandData;
            printf("Enter actual output at 10V load. (ex. Dial=1.08)");
            Vloc = 3;
        }
        else if (Vloc == 3)
        {
            VOLTAGE_CAL_2 = commandData;
            printf("Enter actual output at 8V load. (ex. Dial=0.58)");
            Vloc = 4;
        }
        else if (Vloc == 4)
        {
            VOLTAGE_CAL_3 = commandData;
            Vloc = 0;
            VOLTAGE_12_ACTUAL_VALUE = (VOLTAGE_CAL_1-VOLTAGE_CAL_3)*0.4125;
            printf("\r\n%4.2f, %4.2f", VOLTAGE_CAL_1, VOLTAGE_CAL_3);
            VOLTAGE_12_OFFSET = VOLTAGE_CAL_1-(VOLTAGE_12_ACTUAL_VALUE*12/1.65)+((VOLTAGE_CAL_2-(VOLTAGE_12_ACTUAL_VALUE*10/1.65))*0.5);
            printf("\r\n12V calibration completed.\r\n");
            printf("%4.2f, %4.2f\r\n", VOLTAGE_12_ACTUAL_VALUE, VOLTAGE_12_OFFSET);
        }
        else if (Vloc == -1)
        {
            if (commandData == 1)
            {
                printf("\r\n Enter actual output at 48V load. (ex. Dial=1.52) \r\n");
                Vloc = -2;
            } else{
                printf("Calibration cancelled.");
                Vloc = 0;
            }
        }
        else if (Vloc == -2)
        {
            VOLTAGE_CAL_1 = commandData;
            printf("\r\n Enter actual output at 44V load. (ex. Dial=1.08) \r\n");
            Vloc = -3;
        }
        else if (Vloc == -3)
        {
            VOLTAGE_CAL_2 = commandData;
            printf("\r\n Enter actual output at 40V load. (ex. Dial=0.58) \r\n");
            Vloc = -4;
        }
        else if (Vloc == -4)
        {
            VOLTAGE_CAL_3 = commandData;
            Vloc = 0;
            VOLTAGE_48_ACTUAL_VALUE = (VOLTAGE_CAL_1-VOLTAGE_CAL_3)*0.20625;
            printf("\r\n%4.2f, %4.2f", VOLTAGE_CAL_1, VOLTAGE_CAL_3);
            VOLTAGE_48_OFFSET = VOLTAGE_CAL_1-(VOLTAGE_12_ACTUAL_VALUE*48/1.65)+((VOLTAGE_CAL_2-(VOLTAGE_12_ACTUAL_VALUE*44/1.65))*0.5);
            printf("\r\n48V calibration completed.\r\n");
            printf("%4.2f, %4.2f\r\n", VOLTAGE_12_ACTUAL_VALUE, VOLTAGE_12_OFFSET);
        }
        else if (Vloc == 7)
        {
            if (commandData == 1)
            {
                printf("\r\n Enter actual output at 24V load. (ex. Dial=1.52) \r\n");
                Vloc = 13;
            } else{
                printf("Calibration cancelled.");
                Vloc = 0;
            }
        }
        else if (Vloc == 13)
        {
            VOLTAGE_CAL_1 = commandData;
            printf("\r\n Enter actual output at 21V load. (ex. Dial=1.08) \r\n");
            Vloc = 21;
        }
        else if (Vloc == 21)
        {
            VOLTAGE_CAL_2 = commandData;
            printf("\r\n Enter actual output at 18V load. (ex. Dial=0.58) \r\n");
            Vloc = 42;
        }
        else if (Vloc == 42)
        {
            VOLTAGE_CAL_3 = commandData;
            Vloc = 0;
            VOLTAGE_24_ACTUAL_VALUE = (VOLTAGE_CAL_1-VOLTAGE_CAL_3)*0.275;
            printf("\r\n%4.2f, %4.2f", VOLTAGE_CAL_1, VOLTAGE_CAL_3);
            VOLTAGE_24_OFFSET = VOLTAGE_CAL_1-(VOLTAGE_12_ACTUAL_VALUE*24/1.65)+((VOLTAGE_CAL_2-(VOLTAGE_12_ACTUAL_VALUE*21/1.65))*0.5);
            printf("\r\n24V calibration completed.\r\n");
            printf("%4.2f, %4.2f\r\n", VOLTAGE_12_ACTUAL_VALUE, VOLTAGE_12_OFFSET);
        }
    }
    else if (!strcmp(commandString, "SCL"))
    {
        if (section == 48)
        {
            printf("Not yet implimented.");
        }
        else if (section == 24)
        {
            printf("Not yet implimented.");
        }
        else if (section == 12)
        {
            if (Aloc == 0)
            {
                printf("Begin Voltage 12 current calibration? (Enter Scl=1 to continue)");
                Aloc = -1;
            }
            else if (Aloc == -1)
            {
                if (commandData == 1)
                {
                    printf("Set current to smallest reference point(1/6). Enter actual current amount. (Ex. Scl=1.25)");
                    Aloc = -2;
                } else{
                    printf("Calibration cancelled.");
                    Aloc = 0;
                }
            }
            else if (Aloc == -2)
            {
                CURRENT_IN_1 = commandData;
                adcValues adcVals = getADCresults();
                CURRENT_REF_1 = adcVals.i12;
                printf("Increase input current. Enter new actual input current(2/6).");
                Aloc = -3;
            }
            else if (Aloc == -3)
            {
                CURRENT_IN_2 = commandData;
                adcValues adcVals = getADCresults();
                CURRENT_REF_2 = adcVals.i12;
                printf("Increase input current. Enter new actual input current(3/6).");
                Aloc = -4;
            }
            else if (Aloc == -4)
            {
                CURRENT_IN_3 = commandData;
                adcValues adcVals = getADCresults();
                CURRENT_REF_3 = adcVals.i12;
                printf("Increase input current. Enter new actual input current(4/6).");
                Aloc = -5;
            }
            else if (Aloc == -5)
            {
                CURRENT_IN_4 = commandData;
                adcValues adcVals = getADCresults();
                CURRENT_REF_4 = adcVals.i12;
                printf("Increase input current. Enter new actual input current(5/6).");
                Aloc = -6;
            }
            else if (Aloc == -6)
            {
                CURRENT_IN_5 = commandData;
                adcValues adcVals = getADCresults();
                CURRENT_REF_5 = adcVals.i12;
                printf("Increase input current. Enter new actual input current(6/6).");
                Aloc = -7;
            }
            else if (Aloc == -7)
            {
                CURRENT_IN_6 = commandData;
                adcValues adcVals = getADCresults();
                CURRENT_REF_6 = adcVals.i12;
                Aloc = 0;
                if ((CURRENT_REF_6 - CURRENT_12_OFFSET < 0 && CURRENT_REF_1 - CURRENT_12_OFFSET < 0 && CURRENT_REF_6 > CURRENT_REF_1)
                || (CURRENT_REF_6 - CURRENT_12_OFFSET > 0 && CURRENT_REF_1 - CURRENT_12_OFFSET > 0 && CURRENT_REF_6 < CURRENT_REF_1))
                {
                    CURRENT_12_DIV_THRESH5 = CURRENT_REF_1-CURRENT_12_OFFSET;
                    CURRENT_12_DIV_THRESH4 = CURRENT_REF_2-CURRENT_12_OFFSET;
                    CURRENT_12_DIV_THRESH3 = CURRENT_REF_3-CURRENT_12_OFFSET;
                    CURRENT_12_DIV_THRESH2 = CURRENT_REF_4-CURRENT_12_OFFSET;
                    CURRENT_12_DIV_THRESH1 = CURRENT_REF_5-CURRENT_12_OFFSET;
                    CURRENT_12_DIV_FACTOR5 = (CURRENT_REF_1-CURRENT_12_OFFSET)/CURRENT_IN_1;
                    CURRENT_12_CORRECTION4 = ((CURRENT_REF_1-CURRENT_12_OFFSET)/CURRENT_12_DIV_FACTOR5)-CURRENT_IN_1;
                    CURRENT_12_DIV_FACTOR4 = (CURRENT_REF_2-CURRENT_REF_1)/(CURRENT_IN_2-CURRENT_IN_1);
                    CURRENT_12_CORRECTION4 = ((CURRENT_REF_2-CURRENT_12_OFFSET)/CURRENT_12_DIV_FACTOR4)-CURRENT_IN_2;
                    CURRENT_12_DIV_FACTOR3 = (CURRENT_REF_3-CURRENT_REF_2)/(CURRENT_IN_3-CURRENT_IN_2);
                    CURRENT_12_CORRECTION3 = ((CURRENT_REF_3-CURRENT_12_OFFSET)/CURRENT_12_DIV_FACTOR3)-CURRENT_IN_3;
                    CURRENT_12_DIV_FACTOR2 = (CURRENT_REF_4-CURRENT_REF_3)/(CURRENT_IN_4-CURRENT_IN_3);
                    CURRENT_12_CORRECTION2 = ((CURRENT_REF_4-CURRENT_12_OFFSET)/CURRENT_12_DIV_FACTOR2)-CURRENT_IN_4;
                    CURRENT_12_DIV_FACTOR1 = (CURRENT_REF_5-CURRENT_REF_4)/(CURRENT_IN_5-CURRENT_IN_4);
                    CURRENT_12_CORRECTION1 = ((CURRENT_REF_5-CURRENT_12_OFFSET)/CURRENT_12_DIV_FACTOR1)-CURRENT_IN_5;
                    CURRENT_12_DIV_FACTOR0 = (CURRENT_REF_6-CURRENT_REF_5)/(CURRENT_IN_6-CURRENT_IN_5);
                    CURRENT_12_CORRECTION0 = ((CURRENT_REF_6-CURRENT_12_OFFSET)/CURRENT_12_DIV_FACTOR0)-CURRENT_IN_6;
                }
                else if ((CURRENT_REF_6 - CURRENT_12_OFFSET < 0 && CURRENT_REF_1 - CURRENT_12_OFFSET < 0 && CURRENT_REF_6 < CURRENT_REF_1)
                || (CURRENT_REF_6 - CURRENT_12_OFFSET > 0 && CURRENT_REF_1 - CURRENT_12_OFFSET > 0 && CURRENT_REF_6 > CURRENT_REF_1))
                {
                    CURRENT_12_DIV_THRESH5 = CURRENT_REF_5-CURRENT_12_OFFSET;
                    CURRENT_12_DIV_THRESH4 = CURRENT_REF_4-CURRENT_12_OFFSET;
                    CURRENT_12_DIV_THRESH3 = CURRENT_REF_3-CURRENT_12_OFFSET;
                    CURRENT_12_DIV_THRESH2 = CURRENT_REF_2-CURRENT_12_OFFSET;
                    CURRENT_12_DIV_THRESH1 = CURRENT_REF_1-CURRENT_12_OFFSET;
                    CURRENT_12_DIV_FACTOR0 = (CURRENT_REF_1-CURRENT_12_OFFSET)/CURRENT_IN_1;
                    CURRENT_12_CORRECTION0 = 0;
                    CURRENT_12_DIV_FACTOR1 = (CURRENT_REF_2-CURRENT_REF_1)/(CURRENT_IN_2-CURRENT_IN_1);
                    CURRENT_12_CORRECTION1 = ((CURRENT_REF_2-CURRENT_12_OFFSET)/CURRENT_12_DIV_FACTOR1)-CURRENT_IN_2;
                    CURRENT_12_DIV_FACTOR2 = (CURRENT_REF_3-CURRENT_REF_2)/(CURRENT_IN_3-CURRENT_IN_2);
                    CURRENT_12_CORRECTION2 = ((CURRENT_REF_3-CURRENT_12_OFFSET)/CURRENT_12_DIV_FACTOR2)-CURRENT_IN_3;
                    CURRENT_12_DIV_FACTOR3 = (CURRENT_REF_4-CURRENT_REF_3)/(CURRENT_IN_4-CURRENT_IN_3);
                    CURRENT_12_CORRECTION3 = ((CURRENT_REF_4-CURRENT_12_OFFSET)/CURRENT_12_DIV_FACTOR3)-CURRENT_IN_4;
                    CURRENT_12_DIV_FACTOR4 = (CURRENT_REF_5-CURRENT_REF_4)/(CURRENT_IN_5-CURRENT_IN_4);
                    CURRENT_12_CORRECTION4 = ((CURRENT_REF_5-CURRENT_12_OFFSET)/CURRENT_12_DIV_FACTOR4)-CURRENT_IN_5;
                    CURRENT_12_DIV_FACTOR5 = (CURRENT_REF_6-CURRENT_REF_5)/(CURRENT_IN_6-CURRENT_IN_5);
                    CURRENT_12_CORRECTION5 = ((CURRENT_REF_6-CURRENT_12_OFFSET)/CURRENT_12_DIV_FACTOR5)-CURRENT_IN_6;
                }
                printf("\r\n12V current calibration completed.\r\n");
                //printf("%4.2f, %4.2f\r\n", VOLTAGE_12_ACTUAL_VALUE, VOLTAGE_12_OFFSET);
            }
        }
    }
    else if (!strcmp(commandString, "RCRD"))
    {
        if(checkRange(boardMults, 0, 63) == 1){
            sprintf(storoFrag, "%4.2f", VOLTAGE_48_ACTUAL_VALUE);
            strcat(storoBuild, storoFrag);
            strcat(storoBuild, storoSpace);
            sprintf(storoFrag, "%4.2f", VOLTAGE_48_OFFSET);
            strcat(storoBuild, storoFrag);
            strcat(storoBuild, storoSpace);
            sprintf(storoFrag, "%4.2f", VOLTAGE_24_ACTUAL_VALUE);
            strcat(storoBuild, storoFrag);
            strcat(storoBuild, storoSpace);
            sprintf(storoFrag, "%4.2f", VOLTAGE_24_OFFSET);
            strcat(storoBuild, storoFrag);
            strcat(storoBuild, storoSpace);
            sprintf(storoFrag, "%4.2f", VOLTAGE_12_ACTUAL_VALUE);
            strcat(storoBuild, storoFrag);
            strcat(storoBuild, storoSpace);
            sprintf(storoFrag, "%4.2f", VOLTAGE_12_OFFSET);
            strcat(storoBuild, storoFrag);
            strcat(storoBuild, storoSpace);
            sprintf(storoFrag, "%d", CURRENT_12_DIV_THRESH1);
            strcat(storoBuild, storoFrag);
            strcat(storoBuild, storoSpace);
            sprintf(storoFrag, "%d", CURRENT_12_DIV_THRESH2);
            strcat(storoBuild, storoFrag);
            strcat(storoBuild, storoSpace);
            sprintf(storoFrag, "%d", CURRENT_12_DIV_THRESH3);
            strcat(storoBuild, storoFrag);
            strcat(storoBuild, storoSpace);
            sprintf(storoFrag, "%d", CURRENT_12_DIV_THRESH4);
            strcat(storoBuild, storoFrag);
            strcat(storoBuild, storoSpace);
            sprintf(storoFrag, "%d", CURRENT_12_DIV_THRESH5);
            strcat(storoBuild, storoFrag);
            strcat(storoBuild, storoSpace);
            sprintf(storoFrag, "%d", CURRENT_12_DIV_FACTOR0);
            strcat(storoBuild, storoFrag);
            strcat(storoBuild, storoSpace);
            sprintf(storoFrag, "%4.2f", CURRENT_12_CORRECTION0);
            strcat(storoBuild, storoFrag);
            strcat(storoBuild, storoSpace);
            sprintf(storoFrag, "%d", CURRENT_12_DIV_FACTOR1);
            strcat(storoBuild, storoFrag);
            strcat(storoBuild, storoSpace);
            sprintf(storoFrag, "%4.2f", CURRENT_12_CORRECTION1);
            strcat(storoBuild, storoFrag);
            strcat(storoBuild, storoSpace);
            sprintf(storoFrag, "%d", CURRENT_12_DIV_FACTOR2);
            strcat(storoBuild, storoFrag);
            strcat(storoBuild, storoSpace);
            sprintf(storoFrag, "%4.2f", CURRENT_12_CORRECTION2);
            strcat(storoBuild, storoFrag);
            strcat(storoBuild, storoSpace);
            sprintf(storoFrag, "%d", CURRENT_12_DIV_FACTOR3);
            strcat(storoBuild, storoFrag);
            strcat(storoBuild, storoSpace);
            sprintf(storoFrag, "%4.2f", CURRENT_12_CORRECTION3);
            strcat(storoBuild, storoFrag);
            strcat(storoBuild, storoSpace);
            sprintf(storoFrag, "%d", CURRENT_12_DIV_FACTOR4);
            strcat(storoBuild, storoFrag);
            strcat(storoBuild, storoSpace);
            sprintf(storoFrag, "%4.2f", CURRENT_12_CORRECTION4);
            strcat(storoBuild, storoFrag);
            strcat(storoBuild, storoSpace);
            sprintf(storoFrag, "%d", CURRENT_12_DIV_FACTOR5);
            strcat(storoBuild, storoFrag);
            strcat(storoBuild, storoSpace);
            sprintf(storoFrag, "%4.2f", CURRENT_12_CORRECTION5);
            strcat(storoBuild, storoFrag);
            strcat(storoBuild, storoSpace);
            //SOFBlock::format(sector_index);
            writer.open(sector_index) ;
            writer.write_data((uint8_t*) storoBuild, sizeof storoBuild);
            writer.close();
            testing = TRUE;
        }else{
            showRangeError(1, boardMults, 0.0);
        }
    }
    else if (!strcmp(commandString, "RTRV"))
    {
        reader.open(sector_index);
        storo = reader.get_physical_data_addr();
        reader.close();
        sprintf(storage, "%s", storo);
        int storage_size = strlen(storage);
        char delim[] = ":";
        char *ptr = strtok(storage, delim);
        VOLTAGE_48_ACTUAL_VALUE = atof(ptr);
        ptr = strtok(NULL, delim);
        VOLTAGE_48_OFFSET = atof(ptr);
        ptr = strtok(NULL, delim);
        VOLTAGE_24_ACTUAL_VALUE = atof(ptr);
        ptr = strtok(NULL, delim);
        VOLTAGE_24_OFFSET = atof(ptr);
        ptr = strtok(NULL, delim);
        VOLTAGE_12_ACTUAL_VALUE = atof(ptr);
        ptr = strtok(NULL, delim);
        VOLTAGE_12_OFFSET = atof(ptr);
        ptr = strtok(NULL, delim);
        CURRENT_12_DIV_THRESH1 = atoi(ptr);
        ptr = strtok(NULL, delim);
        CURRENT_12_DIV_THRESH2 = atoi(ptr);
        ptr = strtok(NULL, delim);
        CURRENT_12_DIV_THRESH3 = atoi(ptr);
        ptr = strtok(NULL, delim);
        CURRENT_12_DIV_THRESH4 = atoi(ptr);
        ptr = strtok(NULL, delim);
        CURRENT_12_DIV_THRESH5 = atoi(ptr);
        ptr = strtok(NULL, delim);
        CURRENT_12_DIV_FACTOR0 = atoi(ptr);
        ptr = strtok(NULL, delim);
        CURRENT_12_CORRECTION0 = atof(ptr);
        ptr = strtok(NULL, delim);
        CURRENT_12_DIV_FACTOR1 = atoi(ptr);
        ptr = strtok(NULL, delim);
        CURRENT_12_CORRECTION1 = atof(ptr);
        ptr = strtok(NULL, delim);
        CURRENT_12_DIV_FACTOR2 = atoi(ptr);
        ptr = strtok(NULL, delim);
        CURRENT_12_CORRECTION2 = atof(ptr);
        ptr = strtok(NULL, delim);
        CURRENT_12_DIV_FACTOR3 = atoi(ptr);
        ptr = strtok(NULL, delim);
        CURRENT_12_CORRECTION3 = atof(ptr);
        ptr = strtok(NULL, delim);
        CURRENT_12_DIV_FACTOR4 = atoi(ptr);
        ptr = strtok(NULL, delim);
        CURRENT_12_CORRECTION4 = atof(ptr);
        ptr = strtok(NULL, delim);
        CURRENT_12_DIV_FACTOR5 = atoi(ptr);
        ptr = strtok(NULL, delim);
        CURRENT_12_CORRECTION5 = atof(ptr);
        printf("Values retreived. \r\n");
    }
   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, "RAW"))
   {
      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, "COOK"))
   {
      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