Repository for import to local machine
Dependencies: DMBasicGUI DMSupport
GasChannelDACAndADCPageHandler.cpp
- Committer:
- jmitc91516
- Date:
- 2017-07-31
- Revision:
- 8:26e49e6955bd
- Parent:
- 1:a5258871b33d
File content as of revision 8:26e49e6955bd:
#include "GasChannelDACAndADCPageHandler.h" #include "EasyGUITouchAreaIndices.h" #include "SettingsHandler.h" #include "GetGCStatusLoop.h" #include "NumericKeypadPageHandler.h" #include <stdio.h> #include <stdlib.h> /* Displays the specified easyGUI 'structure' (or page, to use a more easily understood term). Defined in main.cpp */ extern void DisplayEasyGuiStructure(int structureIndex, USBDeviceConnected* usbDevice, USBHostGC* usbHostGC, bool updateEasyGUIVariables = true); /* Converts three eight-bit colour values to the corresponding 16-bit RGB565 value. Defined in main.cpp */ GuiConst_INTCOLOR SixteenBitColorValue(GuiConst_INT8U red, GuiConst_INT8U green, GuiConst_INT8U blue); /* Displays the specified text string at the specified location in the currently-displayed easyGUI page. Defined in main.cpp - and omits the 'ALLOW_DEBUG_PRINTS' #define */ extern void SpecialDebugPrint(char *stuffToPrint, GuiConst_INT16S X, GuiConst_INT16S Y); /* Note that this class is a singleton - we do not need or want there to be more than one instance of it (we do not want multiple values for the carrier gas selection, etc, and nor will we show more than one easyGUI 'GasCalibrationPage' to the user at the same time). */ GasChannelDACAndADCPageHandler * GasChannelDACAndADCPageHandler::theGasChannelDACAndADCPageHandlerInstance = NULL; /* The minimum and maximum values for the DAC value */ const int GasChannelDACAndADCPageHandler::minimumDACValue = 0; const int GasChannelDACAndADCPageHandler::maximumDACValue = 4095; /* We distinguish the 'active' field - i.e. the one being edited by the user - from the inactive field(s), by its background colour */ const GuiConst_INTCOLOR GasChannelDACAndADCPageHandler::inactiveFieldBackgroundColour = SixteenBitColorValue(192, 192, 192); // Grey const GuiConst_INTCOLOR GasChannelDACAndADCPageHandler::activeFieldBackgroundColour = SixteenBitColorValue(255, 255, 0); // Yellow /* Singleton class - return the one and only instance, first creating it if necessary. */ GasChannelDACAndADCPageHandler * GasChannelDACAndADCPageHandler::GetInstance(USBDeviceConnected* newUsbDevice, USBHostGC* newUsbHostGC) { if (theGasChannelDACAndADCPageHandlerInstance == NULL) { theGasChannelDACAndADCPageHandlerInstance = new GasChannelDACAndADCPageHandler(newUsbDevice, newUsbHostGC); } return theGasChannelDACAndADCPageHandlerInstance; } // Singleton class - private constructor GasChannelDACAndADCPageHandler::GasChannelDACAndADCPageHandler(USBDeviceConnected* newUsbDevice, USBHostGC* newUsbHostGC) { usbDevice = newUsbDevice; usbHostGC = newUsbHostGC; } // Private destructor also GasChannelDACAndADCPageHandler::~GasChannelDACAndADCPageHandler() { } /* Saves the current parameter values to QSPI settings, so they are maintained even when the user powers off No arguments, no return value */ void GasChannelDACAndADCPageHandler::SaveGasChannelSelectionToQSPISettings(void) { // Put values to QSPI settings, using SettingsHandler member functions SettingsHandler::PutIntegerValueToQSPISettings("GasDACChannelSelection", channelSelection); } /* Reads the current parameter values from QSPI settings, so they are maintained even when the user powers off No arguments, no return value */ void GasChannelDACAndADCPageHandler::ReadGasChannelSelectionFromQSPISettings(void) { // Get values from QSPI settings, using SettingsHandler member functions // Get round C++ casting rules from integer to enumeration - assign to integer first int intChannelSelection = SettingsHandler::GetIntegerValueFromQSPISettings("GasDACChannelSelection", TOTAL_FLOW); // Correct for possible error (e.g. off by one) if(intChannelSelection < TOTAL_FLOW) intChannelSelection = TOTAL_FLOW; if(intChannelSelection > AIR) intChannelSelection = AIR; channelSelection = (ChannelSelection) intChannelSelection; // Channel index starts at 1 (GC code requires this), but easyGUI radio button indices start at zero GuiVar_gasChannelDACSelection = channelSelection - 1; } /* Tells the caller whether or not the specified touch index is on the easyGUI 'GasChannelDACAndADCPage', and therefore needs to be handled by this class. Args: the touch area index in question Return code: true if the touch area is 'one of ours', false if not */ bool GasChannelDACAndADCPageHandler::TouchAreaIsOnGasChannelDACAndADCPage(int touchAreaIndex) { if((touchAreaIndex >= MIN_GAS_CHANNEL_DAC_AND_ADC_TOUCHINDEX) && (touchAreaIndex <= MAX_GAS_CHANNEL_DAC_AND_ADC_TOUCHINDEX)) { return true; } // 'else' return false; } /* If the specified touch area represents a key or field on the easyGUI 'GasChannelDACAndADCPage', this function performs whatever action is appropriate for it. Provided so that the caller can (in effect) say "if this is one of yours, deal with it", without needing to know anything about what this class does, or how it handles the touch areas on that easyGUI page. Args: the touch area index in question Returns true if it dealt with the touch area (so the caller need not do anything else with the value), or false if it did not deal with the touch area (implying that it was not a touch area on the easyGUI 'GasChannelDACAndADCPage', and so the caller must deal with it some other way). */ bool GasChannelDACAndADCPageHandler::DealWithTouch(int touchAreaIndex) { if(touchAreaIndex == GAS_CHANNEL_DAC_AND_ADC_TOTALFLOW) { if(channelSelection != TOTAL_FLOW) { channelSelection = TOTAL_FLOW; // Channel index starts at 1 (GC code requires this), but easyGUI radio button indices start at zero GuiVar_gasChannelDACSelection = channelSelection - 1; // UpdateEasyGUIPage(); SaveGasChannelSelectionToQSPISettings(); GetGasChannelADCValue(channelSelection, GuiVar_gasChannelDAC_ADCValue); UpdateEasyGUIPage(); // Surely this makes more sense here? } return true; } if(touchAreaIndex == GAS_CHANNEL_DAC_AND_ADC_BACKPRESSURE) { if(channelSelection != BACK_PRESSURE) { channelSelection = BACK_PRESSURE; // Channel index starts at 1 (GC code requires this), but easyGUI radio button indices start at zero GuiVar_gasChannelDACSelection = channelSelection - 1; // UpdateEasyGUIPage(); SaveGasChannelSelectionToQSPISettings(); GetGasChannelADCValue(channelSelection, GuiVar_gasChannelDAC_ADCValue); UpdateEasyGUIPage(); // Surely this makes more sense here? } return true; } if(touchAreaIndex == GAS_CHANNEL_DAC_AND_ADC_FUEL) { if(channelSelection != FUEL) { channelSelection = FUEL; // Channel index starts at 1 (GC code requires this), but easyGUI radio button indices start at zero GuiVar_gasChannelDACSelection = channelSelection - 1; // UpdateEasyGUIPage(); SaveGasChannelSelectionToQSPISettings(); GetGasChannelADCValue(channelSelection, GuiVar_gasChannelDAC_ADCValue); UpdateEasyGUIPage(); // Surely this makes more sense here? } return true; } if(touchAreaIndex == GAS_CHANNEL_DAC_AND_ADC_AIR) { if(channelSelection != AIR) { channelSelection = AIR; // Channel index starts at 1 (GC code requires this), but easyGUI radio button indices start at zero GuiVar_gasChannelDACSelection = channelSelection - 1; // UpdateEasyGUIPage(); SaveGasChannelSelectionToQSPISettings(); GetGasChannelADCValue(channelSelection, GuiVar_gasChannelDAC_ADCValue); UpdateEasyGUIPage(); // Surely this makes more sense here? } return true; } if(touchAreaIndex == GAS_CHANNEL_DAC_AND_ADC_GET_ADC_VALUE_BUTTON) { GetGasChannelADCValue(channelSelection, GuiVar_gasChannelDAC_ADCValue); UpdateEasyGUIPage(); return true; } if(touchAreaIndex == GAS_CHANNEL_DAC_AND_ADC_SET_DAC_VALUE_BUTTON) { SetGasChannelDACValue(channelSelection, GuiVar_gasChannelDAC_DACValue); return true; } if(touchAreaIndex == GAS_CHANNEL_DAC_AND_ADC_DAC_VALUE_EDIT) { NumericKeypadPageHandler* numericKeypadPageHandler = NumericKeypadPageHandler::GetInstance(usbDevice, usbHostGC); if(numericKeypadPageHandler != NULL) { numericKeypadPageHandler->StartEditing(GuiVar_gasChannelDAC_DACValue); numericKeypadPageHandler->SetEasyGUIVariableToEdit(GuiVar_gasChannelDAC_DACValue); numericKeypadPageHandler->SetEasyGUICallingPage(GuiStruct_GasChannelDACAndADCPage_Def); numericKeypadPageHandler->SetEditVariableRange(minimumDACValue, maximumDACValue); numericKeypadPageHandler->SetEditVariableName("DAC"); numericKeypadPageHandler->DisplayEasyGUIPage(); } } // 'else' - none of the above return false; } /* (Re)display the easyGUI 'GasChannelDACAndADCPage' - e.g. after the caller has updated one or more of the easyGUI variables included in the page, and wants to display the new value to the user. No arguments, no return code */ void GasChannelDACAndADCPageHandler::UpdateEasyGUIPage(void) { GetGCStatusLoop *getGCStatusLoop = GetGCStatusLoop::GetInstance(); if(getGCStatusLoop != NULL) { // The GasChannelDACAndADC page has a status rectangle for the gas - // GetGCStatusLoop can display this, we cannot getGCStatusLoop->ForceUpdateOfGasChannelDACAndADCPage(); } } /* Caller is telling us it is about to display the easyGUI 'GasChannelDACAndADCPage', and that we should do whatever we have to do to get it ready, before the caller displays it. No arguments, no return code */ void GasChannelDACAndADCPageHandler::DisplayingEasyGUIPage(void) { ReadGasChannelSelectionFromQSPISettings(); // Make both fields grey - text on page tells user what to do, no need to show them which one is active GuiVar_gasChannelDAC_DACValueBackgroundColour = inactiveFieldBackgroundColour; // = activeFieldBackgroundColour; GuiVar_gasChannelDAC_ADCValueBackgroundColour = inactiveFieldBackgroundColour; GetGasChannelADCValue(channelSelection, GuiVar_gasChannelDAC_ADCValue); } /* Gets the ADC value for the specified gas channel, as a null-terminated string Arguments: the channel number pointer to a buffer to contain the ADC value Returns true on success, false on error */ bool GasChannelDACAndADCPageHandler::GetGasChannelADCValue(int channel, char* buffer) { char cmd[20]; sprintf(cmd, "QGA%1d", channel); char response[50]; while(usbHostGC->ExecutingSetDeviceReport()) {} usbHostGC->SetDeviceReport(usbDevice, cmd, response); //#define DEBUG_PRINTS_HERE #ifdef DEBUG_PRINTS_HERE char dbg[100]; sprintf(dbg, "GetGasChannADC %s %s", cmd, response); SpecialDebugPrint(dbg, 6, 300); #undef DEBUG_PRINTS_HERE #endif // We expect a response like this: "DGAnnnnn", where nnnnn (5 digits) is the ADC value, // or "EPKT" if something went wrong if(response[0] == 'E') { // Assume "EPKT" return false; } //Ensure null terminator response[8] = '\0'; // Ignore leading zeroes - but make sure we leave the final digit, whether zero or not int startIndex; for(startIndex = 3; startIndex < 7; ++startIndex) { if(response[startIndex] != '0') { break; } } strcpy(buffer, &response[startIndex]); return true; } /* Sets the DAC value for the specified gas channel, as a null-terminated string Arguments: the channel number pointer to a buffer that contains the new DAC value, as a null-terminated string Returns true on success, false on error */ bool GasChannelDACAndADCPageHandler::SetGasChannelDACValue(int channel, char* buffer) { char command[20]; sprintf(command, "SGD%1d", channel); int startIndex = 8 - strlen(buffer); int index = 4; while(index < startIndex) { command[index++] = '0'; } int bufferIndex = 0; while(index < 8) { command[index++] = buffer[bufferIndex++]; } command[8] = '\0'; char response[50]; while(usbHostGC->ExecutingSetDeviceReport()) {} usbHostGC->SetDeviceReport(usbDevice, command, response); //#define DEBUG_PRINTS_HERE #ifdef DEBUG_PRINTS_HERE char dbg[100]; sprintf(dbg, "SetGasChannDAC %s %s", command, response); SpecialDebugPrint(dbg, 6, 300); #undef DEBUG_PRINTS_HERE #endif // We expect a "DACK" response, or "DNAK" or "EPKT" if something went wrong if((response[0] == 'E') || (response [1] == 'N')) { // "EPKT" or "DNAK" return false; } return true; }