diff --git a/docs/gq-rfc1201-1.10.txt b/docs/gq-rfc1201-1.10.txt
deleted file mode 100644
index a009e2670c9954a4d5525a40358cc5fd99593db4..0000000000000000000000000000000000000000
--- a/docs/gq-rfc1201-1.10.txt
+++ /dev/null
@@ -1,288 +0,0 @@
-***************************************************
-GQ-RFC1201
-
-GQ Geiger Counter Communication Protocol
-***************************************************
-Ver 1.10
-
-
-Status of this Memo
-
-   This document specifies a GQ GMC Geiger Counter Communication Protocol
-for the
-   communication between GQ GMC Geiger Counter and a computer host via
-serial port, and requests discussion and suggestions for
-   improvements.  Distribution of this memo is unlimited.
-
-Copyright Notice
-
-   Copyright (C) GQ Electronics LLC (2012).  All Rights Reserved.
-
-Abstract
-
-   This document defines a GQ GMC Geiger Counter Communication Protocol
-   to support communication between GMC Geiger Counter and a computer host
-via serial port.  The protocol allows to send data request command from a
-computer host to a GQ GMC geiger counter.
-
-
-**************************
-Serial Port configuration
-**************************
-
-The serial port communication is based on a fixed baud rate.
-
-Baud: 57600
-Data bit: 8
-Parity: None
-Stop bit: 1
-Control: None
-
-
-**************************
-Command format
-**************************
-
-A valid command start with ASCII '<'  and ended with ASCII '>>'. Both
-command and parameters are in between '<' and '>>'.
-
-Command is a ASCII string. All parameters of command are true value in
-hexadecimal.
-
-
-Direction: All commands are initiated from computer(HOST).
-
-
-**************************
-Commands
-**************************
-
-1. Get hardware model and version
-
-Command:  <GETVER>>
-
-
-Return:   total 14 bytes ASCII chars from GQ GMC unit. It includes 7 bytes
-hardware model and 7 bytes firmware version.
-
-	  e.g.:  GMC-300Re 2.10
-
-Firmware supported:  GMC-280, GMC-300 Re.2.0x, Re.2.10 or later
-
-
-2. Get current CPM value
-
-
-Command:  <GETCPM>>
-
-Return:   A 16 bit unsigned integer is returned. In total 2 bytes data
-return from GQ GMC unit. The first byte is MSB byte data and second byte is
-LSB byte data.
-
-	  e.g.: 00 1C     the returned CPM is 28.
-
-Firmware supported:  GMC-280, GMC-300 Re.2.0x, Re.2.10 or later
-
-
-
-3. Turn on the GQ GMC heartbeat
-
-Note:     This command enable the GQ GMC unit to send count per second data
-to host every second automatically.
-
-Command:  <HEARTBEAT1>>
-
-Return:   A 16 bit unsigned integer is returned every second automatically.
-Each data package consist of 2 bytes data from GQ GMC unit. The first byte
-is MSB byte data and second byte is LSB byte data.
-
-
-	 e.g.: 10 1C     the returned 1 second count is 28.   Only lowest 14 bits
-are used for the valid data bit.  The highest bit 15 and bit 14 are reserved
-data bits.
-
-
-
-Firmware supported:  GMC-280, GMC-300  Re.2.10 or later
-
-
-4. Turn off the GQ GMC heartbeat
-
-
-Command:  <HEARTBEAT0>>
-
-Return:   None
-
-Firmware supported:  Re.2.10 or later
-
-
-5. Get battery voltage status
-
-
-Command:  <GETVOLT>>
-
-Return:   one byte voltage value of battery (X 10V)
-
-          e.g.: return 62(hex) is 9.8V
-
-Firmware supported:  GMC-280, GMC-300 Re.2.0x, Re.2.10 or later
-
-
-6. Request history data from internal flash memory
-
-Command:  <SPIR[A2][A1][A0][L1][L0]>>
-
-	A2,A1,A0 are three bytes address data, from MSB to LSB.  The L1,L0 are the
-data length requested.  L1 is high byte of 16 bit integer and L0 is low
-byte.
-
-	The length normally not exceed 4096 bytes in each request.
-
-Return: The history data in raw byte array.
-
-Comment: The minimum address is 0, and maximum address value is the size of
-the flash memory of the GQ GMC Geiger count. Check the user manual for
-particular model flash size.
-
-Firmware supported:  GMC-300 Re.2.0x, Re.2.10 or later
-
-
-7. Get configuration data
-
-Command:  <GETCFG>>
-
-Return: The configuration data.  Total 256 bytes will be returned.
-
-
-Firmware supported:  GMC-280, GMC-300 Re.2.10 or later
-
-
-
-8. Erase all configuration data
-
-Command:  <ECFG>>
-
-Return: 0xAA
-
-Firmware supported: GMC-280, GMC-300 Re.2.10 or later
-
-
-9. Write configuration data
-
-Command:  <WCFG[A0][D0]>>
-
-	A0 is the address and the D0 is the data byte(hex).
-
-Return: 0xAA
-
-Firmware supported: GMC-280, GMC-300 Re.2.10 or later
-
-
-
-10. send a key
-
-Command:  <key[D0]>>
-
-	D0 is the key value from 0 to 3. It represents software key S1~S4.
-Return: none
-
-Firmware supported:  GMC-280, GMC-300 Re.2.0x, Re.2.10 or later
-
-Note: for Re.2.11 or later, each key can be a ASCII string:
-<KEY0>>,<KEY1>>,<KEY2>>,<KEY3>>
-
-
-
-11. get serial number
-
-Command: <GETSERIAL>>
-
-Return: serial number in 7 bytes.
-
-Firmware supported: GMC-280, GMC-300 Re.2.11 or later
-
-
-
-12. Power OFF
-
-Command: <POWEROFF>>
-
-Return: none
-
-Firmware supported: GMC-280, GMC-300 Re.2.11 or later
-
-
-13. Reload/Update/Refresh Configuration
-
-
-Command: <CFGUPDATE>>
-
-Return: 0xAA
-
-Firmware supported: GMC-280, GMC-300 Re.2.20 or later
-
-
-14. Set realtime clock year
-
-command: <SETDATEYY[D0]>>
-
-	D0 is the year value in hexdecimal
-
-Return: 0xAA
-
-Firmware supported: GMC-280, GMC-300 Re.2.23 or later
-
-
-15. Set realtime clock month
-
-command: <SETDATEMM[D0]>>
-
-	D0 is the month value in hexdecimal
-
-Return: 0xAA
-
-Firmware supported: GMC-280, GMC-300 Re.2.23 or later
-
-
-16. Set realtime clock day
-
-command: <SETDATEDD[D0]>>
-
-	D0 is the day of the month value in hexdecimal
-
-Return: 0xAA
-
-Firmware supported: GMC-280, GMC-300 Re.2.23 or later
-
-17. Set realtime clock hour
-
-command: <SETTIMEHH[D0]>>
-
-	D0 is the hourvalue in hexdecimal
-
-Return: 0xAA
-
-Firmware supported: GMC-280, GMC-300 Re.2.23 or later
-
-18. Set realtime clock minute
-
-command: <SETTIMEMM[D0]>>
-
-	D0 is the minute value in hexdecimal
-
-Return: 0xAA
-
-Firmware supported: GMC-280, GMC-300 Re.2.23 or later
-
-
-
-19. Set realtime clock second
-
-command: <SETTIMESS[D0]>>
-
-	D0 is the second value in hexdecimal
-
-Return: 0xAA
-
-Firmware supported: GMC-280, GMC-300 Re.2.23 or later
-
diff --git a/docs/gq-rfc1201-1.40.txt b/docs/gq-rfc1201.txt
similarity index 100%
rename from docs/gq-rfc1201-1.40.txt
rename to docs/gq-rfc1201.txt
diff --git a/gqgmc.cc b/gqgmc.cc
deleted file mode 100644
index bbae33ea9ec63b551449c2db331515a13857464c..0000000000000000000000000000000000000000
--- a/gqgmc.cc
+++ /dev/null
@@ -1,1512 +0,0 @@
-// **************************************************************************
-// File: gqgmc.cc
-//
-// Author:    Phil Gillaspy
-//
-// Last Modified: 04/26/2012
-//
-// Synopsis:
-//   Define the class and its methods describing the capabilities
-//   of the GQ Electronics LLC Geiger-Muller Counter (GQ GMC).
-//   this code applies to model 300 and later geiger counters.
-//
-// CONTINUATION OF DOCUMENTATION FROM gqgmc.hh
-//
-//
-// C++ includes
-#include <string>
-#include <sstream>
-#include <fstream>
-#include <iostream>
-#include <iomanip>
-#include <ios>
-using namespace std;
-
-// These are the C stdio includes needed for configuring the serial port.
-#include <unistd.h>
-#include <fcntl.h>
-#include <termios.h>
-#include <string.h>
-
-// These are GQ GMC project specific includes
-#include "gqgmc.hh"
-using namespace GQLLC;
-
-// LOCAL CONSTANTS
-//
-// GQ GMC COMMANDS
-/*
- Here we declare local constants which are the ASCII strings for the
- various commands to the GQ GMC. These are not declared as data
- members of the GQGMC class because there is just no need to do so.
- The user never need know the actual string commands because there
- is a dedicated public method for each command.
-
- All commands start with '<'. That is followed by ASCII text,
- followed by ">>". Commands which take binary data as parameters
- must be dynamically constructed within the command method.
-*/
-
-static const string  get_serial_cmd        = "<GETSERIAL>>";
-static const string  get_version_cmd       = "<GETVER>>";
-static const string  get_voltage_cmd       = "<GETVOLT>>";
-static const string  get_cpm_cmd           = "<GETCPM>>";
-static const string  get_cps_cmd           = "<GETCPS>>";
-static const string  get_cfg_cmd           = "<GETCFG>>";
-static const string  erase_cfg_cmd         = "<ECFG>>";
-static const string  update_cfg_cmd        = "<CFGUPDATE>>";
-static const string  turn_on_cps_cmd       = "<HEARTBEAT1>>";
-static const string  turn_off_cps_cmd      = "<HEARTBEAT0>>";
-static const string  turn_off_pwr_cmd      = "<POWEROFF>>";
-// The get_history data command has to be formed dynamically since
-// the additional data are parameters of the command.
-// This is also true of the write configuration data command.
-// The send software key command also needs a extra data parameter
-// and so it needs to be formed dynamically.
-// The set time and set date commands also use a hexadecimal parameter
-// and so need to be formed dynamically.
-
-// FIRMWARE CONSTANT
-// Older firmware is any revision prior to 2.23. Not all commands will
-// work on older firmware because some commands were not supported or
-// the command was changed.
-static
-float
-const          kNew_Firmware = 2.23f;
-
-// Size of the NVM configuration data on the GQ GMC
-static
-uint32_t
-const          kNVMSize = 256;
-
-// C STYLE SERIAL PORT CONFIGURATION
-// The termios structure is needed to configure the USB/serial port
-// for baudrate and raw line discipline.
-static struct
-termios        settings;
-
-// debug code
-// LOCAL UTILITIES
-// These Hex.... routines are nice utilities to convert a raw
-// binary byte to an ASCII digit, ie, 1 digit string as hex data.
-// The principle use is to print out the data for debugging.
-// These were plagarized and adapted from code on the internet.
-
-struct HexCharStruct
-{
-  unsigned char c;
-  HexCharStruct(unsigned char _c) : c(_c) { }
-};
-
-static
-std::ostream& operator<<(std::ostream& o, const HexCharStruct& hs)
-{
-  o.width(2);
-  o.fill('0');
-  return (o << std::hex << (int)hs.c);
-}
-
-static
-HexCharStruct Hex(unsigned char _c)
-{
-  return HexCharStruct(_c);
-}
-
-
-// GQGMC CLASS CONSTRUCTOR
-//
-// Constructor implementation needs to initialize the private
-// variables, allocate memory for data history, and determine
-// endianess of processor.
-GQGMC::GQGMC()
-{
-  // CPS is false until proven true
-  mCPS_is_on             = false;
-  // Allocate history_data on heap
-  mHistory_data          = new uint8_t[kHistory_Data_Maxsize];
-  // Determine endianess of host CPU
-  mBig_endian            = isBigEndian();
-} // end GQGMC constructor
-
-
-// GQGMC CLASS DESTRUCTOR
-// Destructor implemented inline in class declaration (see gqgmc.hh)
-
-// SUPPORTING PUBLIC METHODS
-//
-// Method to call to open USB port. We are using classic C style IO
-// because the C++ IO streams did not have enough flexibility to
-// control serial port.  I could not set the baudrate using iostream.
-// Apparently, C++ IO is fixated on files and not hardware devices.
-// Input usb_device_name is the name of the USB to serial device
-// driver name.
-void
-GQGMC::openUSB(string usb_device_name)
-{
-  // Assign name of USB device in private data
-  mUSB_device = usb_device_name;  // for example, /dev/usb/ttyUSB0
-
-  // Open the USB port using a USB to serial converter device driver.
-  // We are using the C stdio open only because it allows the low
-  // level control necessary to set line discpline and baudrate.
-  // The line discpline is raw, that is, no character translation,
-  // no handshaking, no nothing. The return data from the GQ GMC
-  // are always raw binary (well, some of the raw binary might be
-  // ASCII). Output to the GQ GMC is always ASCII with
-  // some commands taking on binary data parameters.
-
-  cout << mUSB_device.c_str() << endl;
-
-  // Open usb serial port for reading and writing.
-  mUSB_serial = open(mUSB_device.c_str(), O_RDWR);
-
-  // If port opened successfully, then proceed to set line discipline.
-  if (mUSB_serial != -1)
-  {
-    mError_code = eNoProblem;
-
-    // Since USB serial is opened successfully, set baud rate to 57600
-    // and other settings to force raw binary data exchange.
-    fcntl(mUSB_serial, F_SETFL, 0);
-
-    memset(&settings,0,sizeof(settings));
-    settings.c_cflag     = CS8 | CREAD | CLOCAL;
-    settings.c_iflag     = 0; // setting line discpline to raw binary
-    settings.c_oflag     = 0;
-    settings.c_lflag     = 0;
-    settings.c_cc[VMIN]  = 0; // This combo of VMIN & VTIME means to wait
-    settings.c_cc[VTIME] = 5; // a maximum of 0.5 seconds for each
-                              // requested or expected byte of data.
-    cfsetispeed(&settings, B57600);
-    cfsetospeed(&settings, B57600);
-    tcsetattr(mUSB_serial, TCSANOW, &settings);
-
-    // Now that the port is successfuly opened, we secretly (unknown to
-    // the user) interrogate the GMC-300 to determine the firmware revision.
-    // For older firmware, a warning is issued to the user. Older firmware
-    // will not support all commands.
-    string vers = getVersion();
-    if (mRead_status == true)
-    {
-      // Parse version string to extract firmware revision. The revision
-      // is a f4.1 formatted string in the last four characters of string.
-      stringstream firmware_rev;
-      firmware_rev << vers[10] << vers[11] << vers[12] << vers[13];
-
-      // Convert revision string to float in order to compare
-      firmware_rev >> mFirmware_revision;
-
-      // There may be a change to commands caused by change to
-      // firmware. We only need to compare if revision is old or new.
-      if (mFirmware_revision < kNew_Firmware)
-        mError_code = eOlder_firmware;
-
-      // Get a fresh copy of the GQ GMC's NVM configuration data.
-      getConfigurationData();
-
-    } // end if (error_code == eNoProblem)
-    // else error_code will have been set by getVersion()
-  }
-  else // usb not opened successfully
-  {
-    mError_code = eUSB_open_failed;
-  } // end  if (usb_serial != -1)
-
-  // It is the responsibility of the caller to test the error_code.
-  return;
-} // end openUSB()
-
-// Method to close USB port is pretty trivial. Implementation is
-// to just close port.
-void
-GQGMC::closeUSB()
-{
-  close(mUSB_serial);
-  return;
-} // end closeUSB()
-
-
-// clearUSB is public method to clear the read (input) buffer of
-// the serial port. This method exists due to vagaries of the
-// turn_on_cps_cmd. Since there is no protocol for the returned
-// data (ie, no start, no stop, no ack, no nak), the synchronization
-// of the getAutoCPS() method with the GQ GMC is flakey. Consequently,
-// when the turn_off_cps_cmd happens, there may be left over
-// data in the USB input buffer. So this method simply reads the
-// USB input buffer until it is empty.
-void
-GQGMC::clearUSB()
-{
-  uint32_t  rcvd(0);
-  char      inp;
-
-  // Assume that there isn't that much left over from any previous
-  // read. In other words, we couldn't ever get that far off.
-  // So read only 10 bytes.
-  const
-  uint16_t  kMaxtries(10);
-
-  // Read returned data until input buffer is empty as indicated by
-  // rcvd = 0 or not. If rcvd = 0 then the buffer is empty and that is
-  // what we want.
-  for(uint16_t i=0; i<kMaxtries; i++)
-  {
-    rcvd = read(mUSB_serial, &inp, 1);
-    if (rcvd == 0) break;
-  } // end for
-
-  // Not good, there are still more characters in input buffer,
-  // so declare error. The calling routine could try again.
-  if (rcvd > 0)
-    mError_code = eClear_USB;
-
-  return;
-}// end clearUSB()
-
-// Public method getErrorCode() to check error code of GQGMC class.
-// Implemented inline in class declaration (see gqgmc.hh)
-
-// Public method to get a text description of the error code. Intended
-// to be used by external code to display this text to user. External
-// code would know the error code from the most recent call to a method.
-// If the error code is non-zero, then call this routine to obtain a
-// textual description of the error.
-string
-GQGMC::getErrorText(gmc_error_t err)
-{
-  stringstream err_msg; // error message returned in this string
-
-  switch(err)
-  {
-    case eNoProblem:  // The user should not call with this error code
-      err_msg << "";
-      break;          // because they are expected to test the code first.
-
-    case eUSB_open_failed:
-      err_msg << "The USB port did not open successfully." << endl;
-      break;
-
-    case eOlder_firmware:
-      err_msg << "Your GQ GMC has older firmware." << endl
-              << "Some commands may not work." << endl;
-      break;
-
-    case eGet_version:
-      err_msg << "The command to read the version number of the firmware "
-              << "failed." << endl;
-      break;
-
-    case eGet_serial_number:
-      err_msg << "The command to read the serial number failed." << endl;
-      break;
-
-    case eGet_CPM:
-      err_msg << "The command to read the counts per minute failed." << endl;
-      break;
-
-    case eGet_CPS:
-      err_msg << "The command to read the counts per second failed." << endl;
-      break;
-
-    case eGet_AutoCPS:
-      err_msg << "The command to read auto counts per second failed." << endl;
-      break;
-
-    case eGet_CFG:
-      err_msg << "The command to get configuration data failed." << endl;
-      break;
-
-    case eErase_CFG:
-      err_msg << "The command to erase configuration data failed." << endl;
-      break;
-
-    case eUpdate_CFG:
-      err_msg << "The command to update configuration data failed." << endl;
-      break;
-
-    case eClear_USB:
-      err_msg << "Failed to clear USB input buffer. You should power "
-              << "cycle GQ GMC." << endl;
-      break;
-
-    case eGet_battery_voltage:
-      err_msg << "The command to read the battery voltage failed." << endl;
-      break;
-
-    case eGet_history_data:
-      err_msg << "The command to read the history data failed." << endl;
-      break;
-    case eGet_history_data_length:
-      err_msg << "The requested data length of the history command cannot "
-              << "exceed " << dec << kHistory_Data_Maxsize << " bytes." << endl;
-      break;
-    case eGet_history_data_address:
-      err_msg << "The address of the history command cannot exceed "
-              << dec << kHistory_Addr_Maxsize << " bytes." << endl;
-      break;
-    case eGet_history_data_overrun:
-      err_msg << "The history data length added to the address cannot exceed "
-              << dec << kHistory_Addr_Maxsize << " bytes." << endl;
-      break;
-
-    case eSet_Year:
-      err_msg << "The set year command failed." << endl;
-      break;
-
-    case eSet_Month:
-      err_msg << "The set month command failed." << endl;
-      break;
-
-    case eSet_Day:
-      err_msg << "The set day command failed." << endl;
-      break;
-
-    case eSet_Hour:
-      err_msg << "The set hour command failed." << endl;
-      break;
-
-    case eSet_Minute:
-      err_msg << "The set minute command failed." << endl;
-      break;
-
-    case eSet_Second:
-      err_msg << "The set second command failed." << endl;
-      break;
-
-    default:          // this should never happen since user should have
-      break;          // obtained a valid code using getErrorCode().
-  } // end switch(err)
-  return err_msg.str();
-} // end get_error_info()
-
-
-// PUBLIC METHODS PROVIDING ACCESS TO GQ GMC CAPABILITIES
-
-// Public method to get GQ geiger counter model name and firmware revision.
-// Example of returned data is "GMC-300Re2.11". Note that this is the only
-// command that has all ASCII as the return data. The command string is
-// get_version_cmd (see GQ  GMC COMMANDS above).
-string
-GQGMC::getVersion()
-{
-  // The GMC returns 14 characters as the version in an alphanumeric string.
-  const
-  uint32_t versize = 14;
-  char     version[versize+1]; // add one for null, '\0'
-
-  // Issue the command to get the version and read the returned data
-  communicate(get_version_cmd, version, versize);
-
-  // If reading data failed, fake returned data and setup error code,
-  if (mRead_status == false)
-  {
-    stringstream ss;
-    ss << "invalidinvalid"; // how convenient, exactly 14 characters
-    ss >> version;
-    mError_code = eGet_version;
-  }
-  // else the version is returned as an ASCII string in version.
-
-  return string(version);
-} // end getVersion()
-
-// Public method to get serial number. The serial number is returned as 7
-// binary bytes. For example, if the GQ GMC returns  00 30 00 E3 4A 35 1A,
-// total 7 bytes in raw binary, then the serial number is "003000E34A351A".
-// Notice how each nibble is effectively a single ASCII hexadecimal digit.
-// The command string is get_serial_cmd (see GQ GMC COMMANDS above).
-string
-GQGMC::getSerialNumber()
-{
-  const
-  uint32_t    sernumsize = 7;             // 7 bytes of returned data
-  char        serial_number[sernumsize+1];// returned data
-  uint8_t     nibble[2*sernumsize];       // each nibble of returned data
-
-  stringstream  ss;
-
-  // Issue the command to get serial number and read returned data.
-  communicate(get_serial_cmd, serial_number, sernumsize);
-
-  // If the read of the returned data succeeded, convert raw data to string.
-  if (mRead_status == true)
-  {
-    // Convert each nibble to an 8-bit int because each nibble
-   	// represents a separate serial number digit.
-    for(uint32_t i=0; i<sernumsize; i++)
-    {
-      nibble[(i*2)]   = (serial_number[i] & 0xF0) >> 4;
-      nibble[(i*2)+1] = (serial_number[i] & 0x0F);
-      // Convert byte array to string of hex ASCII char. Do not use
-      // Hex utility because that forces each arg to have 2 char field.
-      ss << hex << uint16_t(nibble[i*2]) << uint16_t(nibble[(i*2)+1]);
-    }
-  }
-  else // for read failure, set byte array to null and set error code
-  {
-    for(uint32_t i=0; i<sernumsize; i++) nibble[i] = '\0';
-    ss << nibble;
-    mError_code = eGet_serial_number;
-  }
-
-  return ss.str();
-} // end getSerialNumber()
-
-// Public method to get the count per minute value. Command string is
-// get_cpm_cmd (local constants above). The return data is two bytes
-// of binary data. Typically, the background radiation is 10 to 30
-// counts per minute. The command is get_cpm_cmd (see GQ GMC COMMANDS
-// above).
-uint16_t
-GQGMC::getCPM()
-{
-  const
-  uint32_t cpmsize = 2;          // 2 bytes of returned data
-  char     cpm_char[cpmsize+1];  // returned data
-  uint16_t cpm_int = 0;          // this will be the returned value
-
-  // Issue command to get CPM and read returned data
-  communicate(get_cpm_cmd, cpm_char, cpmsize);
-
-  // if read of returned data succeeded, convert raw data to integer
-  if (mRead_status == true)
-  {
-  	// 1st byte is MSB, but note that upper two bits are reserved bits.
-    // Note that shifting and bitmasking performed in uP register, so
-    // endianess is irrevelant.
-    cpm_int |= ((uint16_t(cpm_char[0]) << 8) & 0x3f00);
-    cpm_int |=  (uint16_t(cpm_char[1]) & 0x00ff);
-  }
-  else  // else failure will return cpm = 0 and set error code
-  {
-    mError_code = eGet_CPM;
-  }
-
-  return cpm_int;
-} // end getCPM()
-
-
-// Public method to get the count per second value. Command string is
-// get_cps_cmd (local constants above). The return data is two bytes
-// of binary data. Typically, the background radiation is 0 to 3
-// counts per second. The command is get_cps_cmd (see GQ GMC COMMANDS
-// above).
-uint16_t
-GQGMC::getCPS()
-{
-  const
-  uint32_t cpssize = 2;          // 2 bytes of returned data
-  char     cps_char[cpssize+1];  // returned data
-  uint16_t cps_int = 0;          // this will be the returned value
-
-  // Issue command to get CPM and read returned data
-  communicate(get_cps_cmd, cps_char, cpssize);
-
-  // If read of returned data succeeded, convert raw data to integer
-  if (mRead_status == true)
-  {
-    // 1st byte is MSB, but note that upper two bits are reserved bits.
-    // Note that shifting and bitmasking performed in uP register, so
-    // endianess is irrevelant.
-    cps_int |= ((uint16_t(cps_char[0]) << 8) & 0x3f00);
-    cps_int |=  (uint16_t(cps_char[1]) & 0x00ff);
-  }
-  else  // else failure will return cps = 0 and set error code.
-  {
-    mError_code = eGet_CPS;
-  }
-
-  return cps_int;
-} // end getCPS()
-
-// Public method to read voltage value of battery. The GQ GMC returns
-// a single byte whose integer value converted to a float divided by 10
-// equals the battery voltage. For example, 0x60 = 96 converts to 9.6 Volts.
-// The ideal value is 9.8 volts. So practically speaking, we should not
-// expect to see a value higher than 100. The command is get_voltage_cmd
-// (see GQ GMC COMMANDS above). If the voltage falls below 7.5V, GQ LLC
-// says the geiger counter cannot be expected to operate properly.
-float
-GQGMC::getBatteryVoltage()
-{
-  const
-  uint32_t     voltsize = 1;             // one byte of returned data
-  char         voltage_char[voltsize+1]; // returned data
-  float        voltage(0.0f);            // will be the returned value
-
-  // Issue command to get battery voltage and read returned data.
-  communicate(get_voltage_cmd, voltage_char, voltsize);
-
-  // If read of returned data succeeded, convert raw data to float,
-  if (mRead_status == true)
-  {
-    int32_t  voltage_int = int16_t(voltage_char[0]);
-    voltage = float(voltage_int) / 10.0;
-  }
-  else  // else for failure, voltage is zero and set error code.
-  {
-    mError_code = eGet_battery_voltage;
-  }
-
-  return  voltage;
-} // end getBatteryVoltage()
-
-// Public method to get history data from GQ GMC's history buffer.
-// The user requests the data given the offset into the GQ GMC's 64k
-// byte buffer and the length (amount) of data. The data logging can be
-// set to record either CPM or CPS and the data can be recorded either
-// every second, minute, or hour. The length parameter is the number
-// of bytes to be read, but note that the history data itself is
-// intermixed with special tag data indicating either (1) date/timestamp,
-// (2) uint16 data, or (3) ASCII tag. So the number of bytes read is not
-// the number of data samples. You don't know the number of data
-// samples until you have parsed the history data returned.
-//
-// The date/timestamp string is 55AA00YYMMDDHHMMSS55AADD where
-// 55AA is start of sequence marker,
-// 00 is the enum code that the date/timestamp follows,
-// YY is year, MM is month,
-// HH is 24 hour time, MM is minutes, SS is seconds,
-// 55AA is end of sequence marker,
-// DD is indicator of saved data type where
-// 0 = off (history is off),
-// 1 = CPS every second,
-// 2 = CPM every minute,
-// 3 = CPM recorded once per hour.
-//
-// The uint16 data (two bytes) string is 55AA01DHDL where
-// 55AA is start of sequence marker,
-// 01 is the enum code that two byte data follows,
-// DH is the MSB, DL is the LSB.
-// There is no 55AA end of sequence marker.
-// This particular special tag represents a data sample whose value
-// exceeded 255 and thus needed two bytes. A history buffer of two byte
-// data samples would look something like 55AA02a355AA027555AA01b8 etc.
-// If the radiation is continuously high, then all data will be > 255
-// and the number of data samples in the history buffer will greatly
-// diminished (decreased by factor of 2).
-//
-// The ASCII tag string is 55AA02LLCCCCCCCC.... where
-// 55AA is start of sequence marker,
-// 02 is the enum code indicating that the tag ASCII string follows,
-// LL is the number of ASCII characters in the tag,
-// CC is an ASCII character, there being LL number of ASCII characters.
-// There is no 55AA end of sequence marker.
-//
-// The history data itself is either CPS or CPM. If CPS, the data byte
-// is typically a sequence of 00, 01's, 02's, and occassionally a 03.
-// If CPM, the data is typically anywhere from 0x0a (10 decimal)
-// up to 0x1e (30 decimal). But remember that any time the count per
-// time exceeds 255, then the special 55AADHDL sequence kicks in.
-//
-// The history data continues until either the date/timestamp or label
-// tag special sequences are inserted into the history buffer.
-//
-// If the user requests an area of the history buffer which has no data as
-// yet recorded, then the start of the history buffer is used, in other
-// words, it is as if the user requested address zero.
-//
-// If the user requests a small area of the history buffer, then chances
-// are high that the data retrieved will have no date/timestamp embedded.
-// So it is impossible to know when the data was recorded. The 64K history
-// buffer is divided into 4K blocks and it is guaranteed that there will
-// be a date/timestamp somewhere within each 4K block. For these reasons,
-// the user should request no less than 4K bytes on 4K byte boundary.
-// Note that 4K bytes is also the maximum request allowed. So for all
-// practical purposes, all get history commands should be 4K bytes.
-//
-// The following is typical history buffer log of counts per second
-// (leading 0 is suppressed). Note that the data/timestamp is
-// embedded about half way through (2012, April 1, 17:10).
-// 1 0 1 1 0 0 0 1 0 1 0 0 0 0 2 0 0 0 0 0 0 2 0 0 0 2 0 0 0 0 0 0
-// 0 1 0 0 0 0 0 0 1 0 0 2 0 0 1 0 1 0 2 0 0 0 1 2 1 0 0 0 1 0 1 1
-// 1 1 0 0 0 0 0 0 1 1 0 1 0 0 0 1 0 4 1 0 0 0 0 1 0 0 2 2 0 2 0 0
-// 0 2 1 1 0 0 1 1 0 0 1 1 2 0 0 3 2 0 1 0 0 0 2 0 0 2 0 0 0 0 0 0
-// 0 0 1 2 0 0 0 55 aa 0 c 4 1 11 1f a 55 aa 1 1 0 0 0 0 0 0 1 0 0 0 1 1
-// 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 1 1 1 0 0 0 1 0 1 0 0 0 0 0 1
-// 1 0 0 0 0 0 0 0 1 0 0 1 0 2 1 0 1 2 1 1 0 1 1 0 0 0 0 0 0 0 0 0
-// 0 0 1 0 0 0 0 0 0 2 0 0 0 0 0 1 1 3 0 0 2 0 0 0 0 0 0 1 1 0 1 0
-//
-// The following is a typical history buffer log of counts per
-// minute (leading 0 is suppressed). Note that there are two
-// date/timestamps. The first indicates the current logging is
-// set to counts per second, but the second changes that to
-// counts per minute. Also notice, there is a single two byte
-// sample (55AA021b). The ff data indicates an area of the
-// history buffer that has no data.
-// 0 0 0 0 0 0 1 0 0 0 1 1 0 0 0 0
-// 1 3 0 0 0 0 0 1 1 0 0 2 0 0 0 0
-// 0 0 55 aa 0 c 4 2 11 e 34 55 aa 1 55 aa
-// 0 c 4 2 11 e 35 55 aa 2 1b 16 12 18 18 16
-// 14 13 18 13 18 24 a6 ff ff ff ff ff ff ff ff ff
-// ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
-//
-// Given that the desired amount of history buffer has been
-// retrieved, parsing of the data can proceed by working from the
-// beginning to end or vica versa. Either way, parsing would be
-// looking for the embedded date/timestamp in order to fix the
-// point in time when the data logging begins. The first data
-// sample after the date/timestamp is therefore the beginning of
-// a new recording. Proceeding forward, each successive byte is
-// the next count per second (CPS) or count per minute (CPM) data
-// sample. However, caution must be taken to check for the
-// 55AA sequence which could be either a new date/timestamp or a
-// new label, or a two byte data sample. In the case of a
-// date/timestamp, the parsing must check for a change in the
-// sampling mode, in other words, does the logging change from CPS
-// to CPM or vica versa.
-//
-// The address of the first data sample of the newest log run
-// is maintained in the configuration data as the parameters,
-// dataSaveAddress0, dataSaveAddress1, dataSaveAddress3. This address
-// represents the offset from the beginning of the history buffer.
-// The first data sample will always be preceeded by date/timestamp.
-// So this date/timestamp should be read in order to orient
-// the data log. Any time the sampling mode is changed, the
-// dataSaveAddress0/1/2 is updated, otherwise it remains the same
-// until the logging wraps around to the same address.
-// Incidentally, the configuration data also maintains the parameter,
-// saveDataType, which contains the sampling mode.
-//
-// If you intend to use the GQ GMC to log radiation data for
-// any time longer than a few hours, it is not recommended to
-// use the built-in logging capability of the GQ GMC. Instead,
-// do the logging yourself by simply calling getCPM() method,
-// letting the host computer do the storage and time/date tracking.
-uint8_t * const
-GQGMC::getHistoryData(uint32_t address, uint32_t length)
-{
-  // Initialize history data to zeroes. The max allowed request is
-  // kHistory_Data_Maxsize = 4K bytes. Even if the user requests less
-  // than kHistory_Data_Maxsize, we zero out the whole array.
-  for(uint32_t i=0;i<kHistory_Data_Maxsize;i++)
-    mHistory_data[i] = 0;
-
-  // Check the validity of the input arguments, return if invalid.
-  mError_code = eNoProblem;
-  // 1st check length
-  if (length > kHistory_Data_Maxsize)
-    mError_code = eGet_history_data_length;
-  // check address
-  if (address > kHistory_Addr_Maxsize)
-    mError_code = eGet_history_data_address;
-  // check address plus length
-  if ((address + length) > kHistory_Addr_Maxsize)
-    mError_code = eGet_history_data_overrun;
-  // Trap error here, return immediately if there is an error
-  if (mError_code != eNoProblem)
-    return &mHistory_data[address];
-
-  // Since the request is within boundaries, formulate history command.
-  string get_history_data_cmd = "<SPIR";
-
-  // Pack address and data length into get_history_data_cmd with big
-  // endian byte order.
-
-  // Transmit byte order as MSB first. Note we are using a 32-bit int,
-  // but the MSB will always be 0 since address is max 24 bits in size.
-
-  // pack address
-  get_history_data_cmd += uint8_t((address >> 16) & 0x000000ff); // msb
-  get_history_data_cmd += uint8_t((address >>  8) & 0x000000ff);
-  get_history_data_cmd += uint8_t((address >>  0) & 0x000000ff); // lsb
-
-  // pack length
-  get_history_data_cmd += uint8_t((length >> 8) & 0x00ff);  // lsb
-  get_history_data_cmd += uint8_t((length >> 0) & 0x00ff);  // msb
-
-  // And of course, command finishes with ">>"
-  get_history_data_cmd += ">>";
-
-  // Issue command to get history data and read returned data
-  communicate(get_history_data_cmd, (char *)&mHistory_data[0], length);
-
-  // If read of returned data failed, set error code.
-  if (mRead_status == false)
-  {
-    mError_code = eGet_history_data;
-  }
-
-  // Note that the returned data is a byte array that has to be parsed
-  // further in order to extract the actual history data.
-  return &mHistory_data[0];
-} // end getHistoryData()
-
-// turnOnCPS is public method to enable automatic reporting of the
-// count per second (CPS) value. First, I would say don't use this
-// command. Since the returned data has no protocol, that is, there
-// is no start/stop marker, no identification, no nothing but a
-// sequence of bytes, any other command issued while CPS is turned on
-// will take extraordinary effort not to confuse its returned data
-// with the CPS data. To handle it correctly, you would have to
-// wait for the CPS data to be returned, and then issue the command.
-// This would be most safely done by creating a new thread to
-// read the CPS and using a mutex to signal opportunity to issue a
-// separate command. The command is turn_on_cps_cmd
-// (see GQ GMC COMMANDS above). The returned data is always two
-// bytes so that samples > 255 can be reported (even though unlikely).
-void
-GQGMC::turnOnCPS()
-{
-  sendCmd(turn_on_cps_cmd);
-  // There is no pass/fail return from GQ GMC
-  // Set flag that auto-transmission of CPS is turned on. This is to be
-  // changed to a mutex when threading is implemented.
-  mCPS_is_on = true;
-
-  return;
-} // end turnOnCPS()
-
-// turnOffCPS is the public method to disable automatic reporting
-// of count per second value. The command is turn_off_cps_cmd
-// (see GQ GMC COMMANDS above). Another complication of turning
-// on the auto-CPS, is that turning it off is asynchronous with
-// it being reported. So there may a left over data sample which
-// has to be cleaned up.
-void
-GQGMC::turnOffCPS()
-{
-  sendCmd(turn_off_cps_cmd);
-  // turnOffCPS command has no return data, so there is no way
-  // to know if the  command succeeds or fails.
-  // Set flag of CPS auto-transmission to false
-  mCPS_is_on = false;
-
-  // Since turning off CPS is asynchronous with the GQ GMC's transmission
-  // of the CPS, we will attempt to clear the input buffer of any left
-  // over data.
-  clearUSB();
-
-  return;
-} // end turnOffCPS()
-
-// getAutoCPS is public method to read CPS. This is the method to
-// be called after the user turns on the auto-CPS. If the user has
-// not called turnOnCPS(), then this method will issue error
-// messages.
-uint16_t
-GQGMC::getAutoCPS()
-{
-  const
-  uint32_t cpssize = 2;
-  char     cps_char[cpssize+1];
-  uint16_t cps_int = 0;
-
-  // Issue command to get CPS and read returned data. Note that
-  // we are calling readCmdReturn directly, therefore bypassing
-  // the communicate method. The user should have already issued
-  // turn_on_cps_cmd.
-  readCmdReturn(cps_char, cpssize);
-
-  // If read of returned data succeeded, convert raw data to integer,
-  if (mRead_status == true)
-  {
-    // 1st byte is MSB, but note that upper two bits are reserved
-    // bits. Assume shift & bitmasking take place in register which
-    // is independent of big endian vs little endian architecture.
-    cps_int |= ((uint16_t(cps_char[0]) << 8) & 0x3f00);
-    cps_int |=  (uint16_t(cps_char[1]) & 0x00ff);
-  }
-  else  // else failure will return cps = 0 and set error code
-  {
-    mError_code = eGet_AutoCPS;
-  }
-
-  return cps_int;
-} // end getAutoCPS()
-
-
-// turnOffPower public method turns off the GQ GMC-300. The command
-// is turn_off_pwr_cmd (see GQ GMC COMMANDS above). This will turn
-// off the GQ GMC, so there shouldn't be any other commands issued
-// to the GQ GMC following this command.
-void
-GQGMC::turnOffPower()
-{
-  sendCmd(turn_off_pwr_cmd);
-  // Note that power off cannot fail because the GQ GMC returns nothing.
-  return;
-} // end turnOffPower()
-
-// CONFIGURATION DATA
-//
-// Setting the configuration data of the GQ GMC is not a
-// straight forward procedure. The following statement is the
-// principle reason why: the GQ GMC does not use or keep a RAM copy
-// of its non-volatile memory (NVM) (configuration data is in NVM).
-// That condition coupled with the fact that the EEPROM
-// used by the GQ GMC can only be reprogrammed
-// all 256 bytes at a shot means that if you write a byte of
-// configuration data and then read back the configuration data,
-// you will not see your data changed as expected.
-//
-// All this means that in order to change the configuration
-// parameters and have the GQ GMC change its operations accordingly,
-// 1) the host computer must keep its own copy of NVM,
-// 2) update its own copy of NVM,
-// 3) issue the erase configuration command,
-// 4) write all 256 bytes of configuration data at one shot,
-// 5) follow immediately with an update configuration command.
-//
-// When the GQ GMC receives the update configuration command,
-// then and only then does it re-configure its operation in
-// accordance with the NVM configuration data. Keeping the host
-// computer's copy of the NVM accurate and up to date can be
-// problematic since behind the back of the host computer,
-// the GQ GMC can be changed manually.
-//
-// The GQGMC software makes a valiant attempt to hide all this
-// from the user. First, immediately following the opening of
-// the USB port, the software silently reads the configuration
-// data from the GQ GMC to obtain its own copy of NVM.
-// From that point on, it is assumed that no manual changes
-// to the GQ GMC will occur. The GQGMC software then reads/writes
-// it own local copy of NVM. When the user issues the Update CFG
-// command, the GQGMC software silently
-// 1) issues the erase configuraton command,
-// 2) writes all 256 bytes of NVM,
-// 3) issues the update configuration command.
-
-// The user software may at any time cause a Get configuration
-// command in which case, the user must be aware that the GQGMC's
-// local copy of NVM will be overwritten.
-
-
-// getConfigurationData public method reads configuration data. You
-// don't request pieces of the configuration data, all 256 bytes
-// are returned, although, there are currently only about 60
-// bytes used (corresponding to about 50 parameters). The command is
-// get_cfg_cmd (see GQ GMC COMMANDS above).
-void
-GQGMC::getConfigurationData()
-{
-  // Issue command to get configuration and read returned data.
-  communicate(get_cfg_cmd, reinterpret_cast<char *>(&mCFG_Data),
-                           sizeof(mCFG_Data));
-
-  // If read of returned data failed, set error code.
-  if (mRead_status == false)
-  {
-    mError_code = eGet_CFG;
-  }
-
-  //  debugging code
-  /*
-  uint8_t * inp = (uint8_t *)&mCFG_Data;
-  for(uint32_t i=0; i<64; i++)
-  {
-    cout << Hex(inp[i]) << "-";
-    if (i > 0)
-      if (((i+1)%16) == 0) cout << endl;
-    if (i > 62)break;
-  }
-  cout << endl;
-  */
-  // end debug code
-
-  return;
-} // end getConfigurationData()
-
-// The following get methods are provided in order to access the
-// configuration data, not all configuration data, but only those
-// parameters which are needed to retrieve and parse the history data.
-
-// getSaveDataType is a get method to retrieve the saved data type
-// parameter in the configuration data. Note that SaveDataType is
-// retrieved from the host computer's local copy of NVM
-// configuration data. The return type is an enumeration
-// which matches the following possibilities:
-// 0 = logging is off,
-// 1 = counts per second,
-// 2 = counts per minute,
-// 3 = CPM averaged per hour.
-enum saveDataType_t
-GQGMC::getSaveDataType()
-{
-  return ((enum saveDataType_t)(mCFG_Data.saveDataType));
-} // end getSaveDataType()
-
-
-// setSaveDataType is a set method to reconfigure the data type
-// logged in the history buffer. This method is provided as a
-// convenience instead of using the writeConfigurationData method
-// since changing the saved data type is considered to be
-// more commonly used configuration change. The passed argument
-// is an enumeration (see definition in gqgmc.hh) whose value
-// is to be the new value of the saveDataType configuration
-// parameter. Note that only the host computer's local copy
-// of NVM is updated.  The user must issue a update configuration
-// command to cause the GQGMC to implement the NVM changes.
-void
-GQGMC::setSaveDataType(enum saveDataType_t newSaveDataType)
-{
-  uint8_t  saveData = uint8_t(newSaveDataType);
-
-  // Use writeConfigurationData method
-  writeConfigurationData(eSaveDataType, eSaveDataType_bytecnt, &saveData);
-  // error condition will be handled by writeConfigurationData()
-
-  return;
-} // end setSaveDatatype method
-
-
-// getDataSaveAddress is get method to retrieve the address
-// in the history buffer where the logged data begins. See
-// getHistoryData method for an explanation of the
-// dataSaveAddress in the configuration data structure.
-// The returned value is a 32 bit address, although the
-// dataSaveAddress maximum value cannot exceed 24 bits worth.
-// Note that the DataSaveAddress is retrieved from the host
-// computer's local copy of the GQ GMC's NVM configuration data.
-uint32_t
-GQGMC::getDataSaveAddress()
-{
-  uint32_t      address(0);
-
-  address |= (uint32_t(mCFG_Data.dataSaveAddress2) << 16);
-  address |= (uint32_t(mCFG_Data.dataSaveAddress1) <<  8);
-  address |= (uint32_t(mCFG_Data.dataSaveAddress0) <<  0);
-
-  return address;
-}  // end getDataSaveAddress()
-
-// The resetDataSaveAddress sets the dataSaveAddress configuration
-// parameter to the value of 0x10.  This is provided as a
-// convenience instead of using writeConfigurationData() directly
-// because setting the start of the history buffer back to zero
-// would be a common thing to do. Note that the DataSaveAddress
-// is being updated in the host computer's local copy of the
-// GQ GMC's NVM configuration data. The user must issue the
-// update configuration command to force the GQ GMC to implement
-// the NVM configuration data changes.
-void
-GQGMC::resetDataSaveAddress()
-{
-  uint32_t     address(0x10); // 0x10 provides room for date/timestamp
-
-  // Use writeConfigurationData() method
-  writeConfigurationData(eDataSaveAddress, eDataSaveAddress_bytecnt,
-                         (uint8_t *)(&address));
-  // error condition handled by writeConfigurationData()
-
-  return;
-} // end resetDataSaveAddress()
-
-
-// writeConfiguratonData is the public method to write configuration
-// data. It takes the following parameters.
-//
-// cfgParameter is actually the offset from the beginning of the
-// configuration data of the desired parameter. It was explicitly
-// created this way and assigned the offset as its enumeration value so
-// that cfgParameter serves both as an enumeration and as the actual
-// address of the configuration parameter.
-//
-// cfgData is a pointer to an array of raw binary for the parameter.
-//
-// cfgDataCount is the number of bytes of cfgData. Since cfgData is
-// passed as pointer, we need to supply the array length separately
-// as the cfgDataCount parameter.
-//
-// Note that this method updates the local copy of the GQ GMC's
-// NVM configuration data. As noted previously in the documentation,
-// the GQ GMC does not support a direct method of updating its
-// NVM configuration data and having it take effect immediately.
-//
-// This method is not an exact reflection of the native GQ GMC write
-// configuration command. The native GQ GMC write configuration
-// only writes one byte at a time. So writing multibyte configuration
-// parameters would take multiple writes, one per data byte. Instead,
-// we abstract the write configuration command so the user does not
-// have to know this much detail. We can do this because we
-// know a priori the base address of each parameter and how many
-// bytes each parameter needs. So this method is intended to
-// handle parameters with multibyte data by requiring the user
-// to only pass the parameter enumeration, its byte count, and
-// value.
-//
-// Note that changes to the configuration data do not have
-// immediate effect since we writing to the local copy of the
-// GQ GMC's NVM configuration data. To take effect, the user must
-// call the updateConfigurationData() method. Before doing so, all
-// changes to the configuration data should be completed so that
-// interdependent configuration parameters are updated
-// simultaneously.
-void
-GQGMC::writeConfigurationData(enum cfg_param_t       cfgParameter,
-                              enum cfg_bytecnt_t     cfgDataCount,
-                              uint8_t const * const  cfgData)
-{
-  uint8_t * pCfg_Data = (uint8_t *)&mCFG_Data + uint8_t(cfgParameter);
-  for(int i=0; i<cfgDataCount; i++)
-  {
-    // Convert little endian to big endian which GQ GMC wants.
-    if (mBig_endian)
-      pCfg_Data[i] = cfgData[i];
-    else
-      pCfg_Data[i] = cfgData[cfgDataCount-1-i];
-  } // end for loop
-
-  return;
-} // end writeConfigurationData()
-
-// loadConfigurationData private method writes all 256 bytes
-// of the configuration data to the GQ GMC. This will take
-// over a minute to complete. This is a practice in patience.
-// The GQ GMC's write_cfg_cmd only transmits a single byte
-// at a time. So it takes 256 transmits and each transmit
-// has to wait for a 0xAA return.  The user obviously should
-// not update the NVM configuration too often.
-void
-GQGMC::loadConfigurationData()
-{
-  const
-  uint32_t     retsize = 1;
-  char         ret_char[retsize+1];
-
-  // Need a pointer to the local host computer's copy
-  // of the NVM configuration data.
-  uint8_t *    pCfg_Data = (uint8_t *)&mCFG_Data;
-
-  // Begin formulating the write configuration data command.
-  // "AD" is just a place holder for the address byte and data byte
-  // that will be dynamically derived and inserted.
-  string write_cfg_cmd = "<WCFGAD>>";
-
-  // The parameter and its data have to be dynamically derived.
-  // write_cfg_cmd[5] is parameter enumeration (aka address offset)
-  // write_cfg_cmd[6] is parameter data
-
-  // Pack address and data into write_cfg_data_cmd with big
-  // endian byte order.
-
-  // Address (ie, parameter) is less than 256 since configuration
-  // data has a fixed size of 256 bytes, so address is one byte.
-
-  // pack address and data into command
-  for(uint16_t i=0; i<kNVMSize; i++)
-  {
-    // Increment the address for each additional data byte.
-    write_cfg_cmd[5] = uint8_t(i);
-
-    // Load data one byte at a time
-    write_cfg_cmd[6] = pCfg_Data[i];
-
-/*    // debug code
-    if (i < 64)
-    {
-      for(int i=0; i<5; i++)
-        cout << write_cfg_cmd[i];
-      cout << Hex(write_cfg_cmd[5]);
-      cout << Hex(write_cfg_cmd[6]);
-      cout << write_cfg_cmd[7];
-      cout << write_cfg_cmd[8];
-      cout << endl;
-    }
-*/    // end debug code
-
-    // Issue command to write configuration data, one byte
-    // at a time because that is the native write configuration
-    // command of the GQ GMC.
-    communicate(write_cfg_cmd, ret_char, retsize);
-
-    // if read of returned data succeeded, convert raw data to float
-    if (mRead_status == true)
-    {
-      // We really don't care about the return value of 0xAA. If the
-      // GQ GMC does not recognize the command, it returns nothing and
-      // we get a read_status error.
-    }
-    else  // else for failure, set error code
-    {
-      mError_code = eWrite_CFG;
-      break;                    // break out of for loop
-    } // end (read_status == true)
-  } // end for loop
-
-  return;
-} // loadConfigurationData()
-
-// eraseConfigurationData public method erases the configuration data
-// in its entirety. The configuration returns to its factory default
-// setting. It might have been better to call this the reset
-// configuration data command. The command is erase_cfg_cmd
-// (see GQ GMC COMMANDS above).
-void
-GQGMC::eraseConfigurationData()
-{
-  const
-  uint32_t     retsize = 1;
-  char         ret_char[retsize+1];
-
-  // Issue command to erase NVM configuration.
-  communicate(erase_cfg_cmd, ret_char, retsize);
-
-  // If read of returned data succeeded, convert raw data to float,
-  if (mRead_status == true)
-  {
-    // We really don't care about the return value of 0xAA. If the
-    // GQ GMC does not recognize the command, it returns nothing and
-    // we get a read_status error.
-  }
-  else  // else for failure, set the error code.
-  {
-    mError_code = eErase_CFG;
-  }
-
-  return;
-} // end eraseConfigurationData()
-
-
-// The updateConfigurationdata public method is called to make changes
-// to configuration data take effect. All other methods to modify
-// the configuration data do not cause the GQ GMC to immediately
-// change operation. This would not be desireable since various
-// changes to the configuration may be interdependent and so
-// we would want the changes to take effect simultaneously to
-// insure proper operation. There are no arguments to call.
-// The command is update_cfg_cmd (see GQ GMC COMMANDS above).
-// The user who calls this method may want to pop-up a window
-// stating that this will take about one minute. That is about
-// how long it will take to write all 256 bytes to the GQ GMC.
-// This method calls eraseConfigurationData() and
-// loadConfigurationData() as part of the procedure needed to
-// force the GQ GMC to implement operational changes per the
-// new NVM configuration data.
-void
-GQGMC::updateConfigurationData()
-{
-  const
-  uint32_t     retsize = 1;
-  char         ret_char[retsize+1];
-
-    // 1st, we have to erase configuration data
-  // cout << erase_cfg_cmd << endl; // debug
-  eraseConfigurationData();
-  // 2nd, write all 256 bytes of NVM to GQ GMC
-  // cout << "load cfg" << endl; // debug
-  loadConfigurationData();
-
-  // cout << update_cfg_cmd << endl; // debug
-  // Issue command to update NVM and force GQ GMC to change
-  // operation in accordance to new configuration data.
-  communicate(update_cfg_cmd, ret_char, retsize);
-
-  // If read of returned data succeeded, convert raw data to float,
-  if (mRead_status == true)
-  {
-    // We really don't care about the return value of 0xAA. If the
-    // GQ GMC does not recognize the command, it returns nothing and
-    // we get a read_status error.
-  }
-  else  // else for failure, set the error code.
-  {
-    mError_code = eUpdate_CFG;
-  }
-
-  return;
-} // end updateConfigurationData()
-
-
-// sendKey is the public method to emulate any one of the 4 keys on
-// the front panel of the GQ GMC. The front panel has a 'left arrow',
-// 'up arrow, 'down arrow', and 'enter' keys. These are used to
-// navigate through the GQ GMC's menu system. In principle, the
-// menu system can be used to set virtually any and all of the
-// configuration data (although this is not recommended for
-// such configuration data as the calibration values).
-// So instead of the writeConfigurationData method,
-// the proper sequence of sending the keys would do the
-// same thing. The command is derived dynamically, but the actual
-// command is "<KEY0>>" or "<KEY1>>" or "<KEY2>>" or "<KEY3>>".
-// So for the purpose that the user need not know the actual
-// command string, the softkey_t enumeration is created and used
-// as the passed argument to the method. See the enum softkey_t
-// declaration in gqgmc.hh for more discussion.
-//
-// For successive sendKey calls there is a trick to know when
-// using the sendKey method. The trick is you can't
-// transmit sendKey too fast and you can't do it too slow.
-// Another thing is that the Save Data option menu starts with
-// the current data type and then cycles through the other options.
-// So you have to know what is the current data type and
-// then send the Enter key the proper number of times to cycle
-// to the desired option. When moving through the menu we use
-// 0.5 seconds, but when moving through a pop up options menu
-// we have to move faster and so should use 0.25 seconds
-// between sendKey in that context.
-void
-GQGMC::sendKey(enum softkey_t key)
-{
-  char   inp[1]; // This will not be used, just needed as dummy arg
-
-  // Begin formulating the send key command.
-  string keycmd = "<KEY";
-
-  // Append key number which is an enumeration equal to the
-  // ASCII value of the key, ie, '0', '1', '2', or '3'.
-  keycmd += uint8_t(key);
-  // Append ">>"
-  keycmd += ">>";
-
-  communicate(keycmd, inp, 0);  // no return data
-  // Since the sendkey command returns no data there is no way to
-  // test success of communication.
-
-  // Debug code
-/*
-  for(int i=0; i<7; i++)
-    cout << Hex(keycmd[i]);
-  cout << endl;
-*/
-  return;
-} // end sendKey()
-
-
-// setDate is the public method to set the date. The date is passed as
-// an ASCII string with the format of <month><day><year>, for example,
-// 112312 is November (11th month) 12, 2012.  The year is specified
-// as the last two digits of the century since presumably the date is
-// is being set to the current date. In reality, the GQ GMC has a separate
-// command for setting each of the month, day, and year.
-void
-GQGMC::setDate(string date)
-{
-  const
-  uint32_t     retsize = 1;
-  char         ret_char[retsize+1];
-
-  // The date is broken up into three separate commands one each for
-  // month, day, and year as supported by the GQ GMC.
-
-  // Set the month, <SETDATEMMXX>> where XX = month byte.
-  {
-    // uint16_t is necessary since ss >> uint8_t does not work.
-    uint16_t      month=0;
-    string        setMonthCmd;
-    stringstream  ss;
-    ss << date[0] << date[1];
-    ss >> month;
-    //cout << "month = " << Hex(uint8_t(month)) << endl;
-    setMonthCmd  = "<SETDATEMM";
-    setMonthCmd += uint8_t(month);
-    setMonthCmd += ">>";
-    communicate(setMonthCmd, ret_char, retsize);
-  }
-
-  // Set the day, <SETDATEDDXX>> where XX = day byte.
-  {
-    uint16_t      day=0;
-    string        setDayCmd;
-    stringstream  ss;
-    ss << date[2] << date[3];
-    ss >> day;
-    //cout << "day = " << Hex(uint8_t(day)) << endl;
-    setDayCmd  = "<SETDATEDD";
-    setDayCmd += uint8_t(day);
-    setDayCmd += ">>";
-    communicate(setDayCmd, ret_char, retsize);
-  }
-
-  // Set the year, <SETDATEYYXX>> where XX = year byte.
-  {
-    uint16_t      year=0;
-    string        setYearCmd;
-    stringstream  ss;
-    ss << date[4] << date[5];
-    ss >> year;
-    //cout << "year = " << Hex(uint8_t(year)) << endl;
-    setYearCmd  = "<SETDATEYY";
-    setYearCmd += uint8_t(year);
-    setYearCmd += ">>";
-    communicate(setYearCmd, ret_char, retsize);
-  }
-
-  return;
-} // end set Date()
-
-// setTime is the public method to set the time of day. The time is
-// passed as an ASCII string with the format of <hour><minutes><seconds>,
-// for example, 142256 is the 14th hour, 22 minutes after the hour,
-// 56 seconds after the minute.  The hour is given in 24 hour format
-// counting from 0 to 23. In reality, the GQ GMC provides a separate
-// command for setting each of the hour, minutes and seconds.
-void
-GQGMC::setTime(string time)
-{
-    const
-    uint32_t     retsize = 1;
-    char         ret_char[retsize+1];
-
-    // The time is broken up into three separate commands one each for
-    // hour, minute, and second as supported by the GQ GMC.
-
-    // Set the hour, <SETTIMEHHXX>> where XX = hour byte.
-    {
-      uint16_t      hour=0;       // stringstream does not convert to uint8_t
-      string        setHourCmd;
-      stringstream  ss;
-      ss << time[0] << time[1];
-      ss >> hour;
-      //cout << "hours = " << Hex(uint8_t(hour)) << endl;
-      setHourCmd  = "<SETTIMEHH";
-      setHourCmd += uint8_t(hour);
-      setHourCmd += ">>";
-      communicate(setHourCmd, ret_char, retsize);
-    }
-
-    // Set the minute, <SETTIMEMMXX>> where XX = minute byte.
-    {
-      uint16_t      minute=0;
-      string        setMinuteCmd;
-      stringstream  ss;
-      ss << time[2] << time[3];
-      ss >> minute;
-      //cout << "minute = " << Hex(uint8_t(minute)) << endl;
-      setMinuteCmd  = "<SETTIMEMM";
-      setMinuteCmd += uint8_t(minute);
-      setMinuteCmd += ">>";
-      communicate(setMinuteCmd, ret_char, retsize);
-    }
-
-    // Set the seconds, <SETTIMESSXX>> where XX = second byte.
-    {
-      uint16_t      second=0;
-      string        setSecondCmd;
-      stringstream  ss;
-      ss << time[4] << time[5];
-      ss >> second;
-      //cout << "second = " << Hex(uint8_t(second)) << endl;
-      setSecondCmd  = "<SETTIMESS";
-      setSecondCmd += uint8_t(second);
-      setSecondCmd += ">>";
-      communicate(setSecondCmd, ret_char, retsize);
-    }
-
-  return;
-} // end setTime()
-
-
-// PRIVATE METHODS
-
-// communicate private method is used to write/read data to/from
-// the GMC-300. This method is expressedly designed to be called
-// by methods which send an ASCII string and expect to receive
-// returned data. However for flexibility, if the command string
-// is null, no command is transmitted and if the expected number
-// of return bytes is zero, no read is performed.
-// cmd is the ASCII string command.
-// retdata is the repository for the returned data.
-// retbytes is the number of bytes of returned data.
-void
-GQGMC::communicate(const string cmd, char * retdata, uint32_t retbytes)
-{
-  // Clear the USB port of any left over data from last exchange. Even
-  // though we know how many bytes the GQ GMC transmits for each
-  // command, experience has shown this is the safe thing to do since
-  // there is no protocol for the returned data.
-  clearUSB();
-
-  //cout << cmd << endl;
-  // 1st, issue the command to the GMC-300, this is always an ASCII
-  // string.
-  // For flexibility, only transmit if cmdbytes is not 'null'.
-  if (cmd.size() > 0) sendCmd(cmd);
-  // 2nd, read the return data, for all commands except get version
-  // this is always raw binary data.
-  // For flexibility, only read if return is not 'null'.
-  if (retbytes > 0) readCmdReturn(retdata, retbytes);
-
-  return;
-} // end communicate()
-
-// sendCmd is the private method (the basic method) to transmit
-// the command to the GMC-300.
-// cmd is the ASCII string to send as the command.
-void
-GQGMC::sendCmd(const string cmd)
-{
-  // This is a common place to reset the error code since it is always
-  // called for any command.
-  mError_code = eNoProblem;
-
-  // This is a common place to reset the read status since every read
-  // is always preceeded by a write command (except for turn_on_cps!).
-  mRead_status = true;
-
-  // Call low level C stdio routine to write to USB port.
-  write(mUSB_serial, cmd.c_str(), cmd.size());
-
-  return;
-} // end sendCmd()
-
-// readCmdReturn is the private method (the basic method) to read
-// the return bytes from the command.
-// retdata is the repository for the returned data.
-// retbytes is the number of bytes of the returned data.
-void
-GQGMC::readCmdReturn(char * retdata, uint32_t retbytes)
-{
-  uint32_t rcvd = 0;           // the number of received bytes
-  char * inp    = &retdata[0]; // pointer to returned data char array
-                               // start pointer off at beginning of
-                               // repository.
-
-  // Assume read will succeed, replicated here only because of the
-  // nature of the turn_on_cps command which automatically returns
-  // data without a preceeding write.
-  mRead_status = true;
-
-  // Now read the returned raw byte string. Do this by reading one byte
-  // at a time until the requested number of bytes are attained. However,
-  // the serial port has been setup to timeout each read attempt. So if
-  // after N calls to read, we haven't yet read all N bytes, declare
-  // a failure. The read is done this way to avoid an indefinite blocking
-  // situation when 0 bytes are returned by the GQ GMC. The only good thing
-  // about this methodology is that the largest possible read is only 4K
-  // for the history data. So the read never really takes that much time.
-  for(uint32_t i=0; i<retbytes; i++)
-  {
-    rcvd += read(mUSB_serial, inp, 1);
-    inp   = &retdata[rcvd];
-    if (rcvd >= retbytes) break;
-  } // end for loop
-
-  //  debugging code
-  /*
-  inp = &retdata[0];
-  for(uint32_t i=0; i<retbytes; i++)
-  {
-    cout << Hex(inp[i]) << "-";
-    if (i > 0)
-      if (((i+1)%16) == 0) cout << endl;
-    if (i > 62)break;
-  }
-  cout << endl;
-  cout << "rcvd = " << rcvd << endl;
-  */
-  // end debug code
-
-  // Communication is considered a failure if less than the expected
-  // number of bytes is returned by the GMC-300.
-  if (rcvd < retbytes)
-    mRead_status = false;
-
-  return;
-} // readCmdReturn()
-
-// isBigEndian is the method to determine endianess of host CPU.
-// This is to be called by constructor once and once only. This is
-// needed because the GQ GMC wants data transmitted to it in
-// big endian and returns data in big endian, but the host computer
-// could be little endian. The routine was adapted from code
-// found on the internet.
-bool
-GQGMC::isBigEndian(void)
-{
-  uint32_t x(0xff);
-  bool bigend(reinterpret_cast<unsigned char *>(&x)[0] == 0);
-  return bigend;
-} // end isBigEndian()
-
-// end file gqgmc.cc