John Mitchell / lpc4088_displaymodule_GC500_2_5inch

Dependencies:   DMBasicGUI DMSupport

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers GasChannelDACAndADCPageHandler.cpp Source File

GasChannelDACAndADCPageHandler.cpp

00001 #include "GasChannelDACAndADCPageHandler.h"
00002 #include "EasyGUITouchAreaIndices.h"
00003 #include "SettingsHandler.h"
00004 #include "GetGCStatusLoop.h"
00005 #include "NumericKeypadPageHandler.h"
00006 
00007 #include <stdio.h>
00008 #include <stdlib.h>
00009 
00010 
00011 
00012 /*
00013     Displays the specified easyGUI 'structure' (or page, to use a more easily understood term).
00014     Defined in main.cpp
00015 */
00016 extern void DisplayEasyGuiStructure(int structureIndex, USBDeviceConnected* usbDevice, USBHostGC* usbHostGC, bool updateEasyGUIVariables = true);
00017 
00018 
00019 /*
00020     Converts three eight-bit colour values to the corresponding 16-bit RGB565 value.
00021     Defined in main.cpp
00022 */
00023 GuiConst_INTCOLOR SixteenBitColorValue(GuiConst_INT8U red, GuiConst_INT8U green, GuiConst_INT8U blue); 
00024 
00025 
00026 /*
00027     Displays the specified text string at the specified location in the currently-displayed easyGUI page.
00028     
00029     Defined in main.cpp - and omits the 'ALLOW_DEBUG_PRINTS' #define
00030 */
00031 extern void SpecialDebugPrint(char *stuffToPrint, GuiConst_INT16S X, GuiConst_INT16S Y);
00032 
00033 
00034 /*                      
00035     Note that this class is a singleton - we do not need or want there to be more than one instance of it
00036     (we do not want multiple values for the carrier gas selection, etc, and nor will we show 
00037     more than one easyGUI 'GasCalibrationPage' to the user at the same time).
00038 */
00039 GasChannelDACAndADCPageHandler * GasChannelDACAndADCPageHandler::theGasChannelDACAndADCPageHandlerInstance = NULL;
00040 
00041 
00042 /*
00043     The minimum and maximum values for the DAC value 
00044 */
00045 const int GasChannelDACAndADCPageHandler::minimumDACValue = 0;
00046 const int GasChannelDACAndADCPageHandler::maximumDACValue = 4095;
00047     
00048 /*
00049     We distinguish the 'active' field - i.e. the one being edited by the user - 
00050     from the inactive field(s), by its background colour
00051 */
00052 const GuiConst_INTCOLOR GasChannelDACAndADCPageHandler::inactiveFieldBackgroundColour = SixteenBitColorValue(192, 192, 192); // Grey
00053 const GuiConst_INTCOLOR GasChannelDACAndADCPageHandler::activeFieldBackgroundColour   = SixteenBitColorValue(255, 255, 0); // Yellow
00054 
00055 
00056 /*
00057     Singleton class - return the one and only instance, first creating it if necessary.
00058 */
00059 GasChannelDACAndADCPageHandler * GasChannelDACAndADCPageHandler::GetInstance(USBDeviceConnected* newUsbDevice, USBHostGC* newUsbHostGC)
00060 {
00061     if (theGasChannelDACAndADCPageHandlerInstance == NULL) {
00062         theGasChannelDACAndADCPageHandlerInstance = new GasChannelDACAndADCPageHandler(newUsbDevice, newUsbHostGC);
00063     }
00064     
00065     return theGasChannelDACAndADCPageHandlerInstance;
00066 }
00067 
00068 // Singleton class - private constructor
00069 GasChannelDACAndADCPageHandler::GasChannelDACAndADCPageHandler(USBDeviceConnected* newUsbDevice, USBHostGC* newUsbHostGC)
00070 {
00071     usbDevice = newUsbDevice;
00072     usbHostGC = newUsbHostGC;
00073 }
00074 
00075 // Private destructor also
00076 GasChannelDACAndADCPageHandler::~GasChannelDACAndADCPageHandler()
00077 {
00078     
00079 }
00080 
00081 /*
00082     Saves the current parameter values to QSPI settings,
00083     so they are maintained even when the user powers off
00084     
00085     No arguments, no return value
00086 */
00087 void GasChannelDACAndADCPageHandler::SaveGasChannelSelectionToQSPISettings(void)
00088 {
00089     // Put values to QSPI settings, using SettingsHandler member functions
00090 
00091     SettingsHandler::PutIntegerValueToQSPISettings("GasDACChannelSelection", channelSelection);
00092 }
00093 
00094 
00095 /*
00096     Reads the current parameter values from QSPI settings,
00097     so they are maintained even when the user powers off
00098     
00099     No arguments, no return value
00100 */
00101 void GasChannelDACAndADCPageHandler::ReadGasChannelSelectionFromQSPISettings(void)
00102 {
00103     // Get values from QSPI settings, using SettingsHandler member functions
00104     
00105     // Get round C++ casting rules from integer to enumeration - assign to integer first
00106     int intChannelSelection = SettingsHandler::GetIntegerValueFromQSPISettings("GasDACChannelSelection", TOTAL_FLOW);
00107     
00108     // Correct for possible error (e.g. off by one)
00109     if(intChannelSelection < TOTAL_FLOW) intChannelSelection = TOTAL_FLOW;
00110     if(intChannelSelection > AIR) intChannelSelection = AIR;
00111     
00112     channelSelection = (ChannelSelection) intChannelSelection;
00113     
00114     // Channel index starts at 1 (GC code requires this), but easyGUI radio button indices start at zero
00115     GuiVar_gasChannelDACSelection = channelSelection - 1;
00116 }
00117 
00118 
00119 /*
00120     Tells the caller whether or not the specified touch index is on the easyGUI 'GasChannelDACAndADCPage',
00121     and therefore needs to be handled by this class.
00122     
00123     Args: the touch area index in question
00124     
00125     Return code: true if the touch area is 'one of ours', false if not
00126 */
00127 bool GasChannelDACAndADCPageHandler::TouchAreaIsOnGasChannelDACAndADCPage(int touchAreaIndex)
00128 {
00129     if((touchAreaIndex >= MIN_GAS_CHANNEL_DAC_AND_ADC_TOUCHINDEX) && (touchAreaIndex <= MAX_GAS_CHANNEL_DAC_AND_ADC_TOUCHINDEX)) {
00130         return true;
00131     }
00132     
00133     // 'else'
00134     return false;
00135 }
00136 
00137 
00138 /*
00139     If the specified touch area represents a key or field on the easyGUI 'GasChannelDACAndADCPage',
00140     this function performs whatever action is appropriate for it. Provided so that the caller
00141     can (in effect) say "if this is one of yours, deal with it", without needing to know 
00142     anything about what this class does, or how it handles the touch areas on that easyGUI page.
00143 
00144     Args: the touch area index in question
00145     
00146     Returns true if it dealt with the touch area (so the caller need not do anything else 
00147     with the value), or false if it did not deal with the touch area (implying that it 
00148     was not a touch area on the easyGUI 'GasChannelDACAndADCPage', and so the caller
00149     must deal with it some other way).
00150 */
00151 bool GasChannelDACAndADCPageHandler::DealWithTouch(int touchAreaIndex)
00152 {
00153     if(touchAreaIndex == GAS_CHANNEL_DAC_AND_ADC_TOTALFLOW) {
00154         if(channelSelection != TOTAL_FLOW) {
00155             channelSelection = TOTAL_FLOW;
00156             // Channel index starts at 1 (GC code requires this), but easyGUI radio button indices start at zero
00157             GuiVar_gasChannelDACSelection = channelSelection - 1;
00158 //            UpdateEasyGUIPage();
00159             SaveGasChannelSelectionToQSPISettings();
00160             GetGasChannelADCValue(channelSelection, GuiVar_gasChannelDAC_ADCValue);
00161             UpdateEasyGUIPage(); // Surely this makes more sense here?
00162         }
00163         return true;
00164     }    
00165     
00166     if(touchAreaIndex == GAS_CHANNEL_DAC_AND_ADC_BACKPRESSURE) {
00167         if(channelSelection != BACK_PRESSURE) {
00168             channelSelection = BACK_PRESSURE;
00169             // Channel index starts at 1 (GC code requires this), but easyGUI radio button indices start at zero
00170             GuiVar_gasChannelDACSelection = channelSelection - 1;
00171 //            UpdateEasyGUIPage();
00172             SaveGasChannelSelectionToQSPISettings();
00173             GetGasChannelADCValue(channelSelection, GuiVar_gasChannelDAC_ADCValue);
00174             UpdateEasyGUIPage(); // Surely this makes more sense here?
00175         }
00176         return true;
00177     }    
00178     
00179     if(touchAreaIndex == GAS_CHANNEL_DAC_AND_ADC_FUEL) {
00180         if(channelSelection != FUEL) {
00181             channelSelection = FUEL;
00182             // Channel index starts at 1 (GC code requires this), but easyGUI radio button indices start at zero
00183             GuiVar_gasChannelDACSelection = channelSelection - 1;
00184 //            UpdateEasyGUIPage();
00185             SaveGasChannelSelectionToQSPISettings();
00186             GetGasChannelADCValue(channelSelection, GuiVar_gasChannelDAC_ADCValue);
00187             UpdateEasyGUIPage(); // Surely this makes more sense here?
00188         }
00189         return true;
00190     }    
00191     
00192     if(touchAreaIndex == GAS_CHANNEL_DAC_AND_ADC_AIR) {
00193         if(channelSelection != AIR) {
00194             channelSelection = AIR;
00195             // Channel index starts at 1 (GC code requires this), but easyGUI radio button indices start at zero
00196             GuiVar_gasChannelDACSelection = channelSelection - 1;
00197 //            UpdateEasyGUIPage();
00198             SaveGasChannelSelectionToQSPISettings();
00199             GetGasChannelADCValue(channelSelection, GuiVar_gasChannelDAC_ADCValue);
00200             UpdateEasyGUIPage(); // Surely this makes more sense here?
00201         }
00202         return true;
00203     }    
00204     
00205     if(touchAreaIndex == GAS_CHANNEL_DAC_AND_ADC_GET_ADC_VALUE_BUTTON) {
00206         GetGasChannelADCValue(channelSelection, GuiVar_gasChannelDAC_ADCValue);
00207         UpdateEasyGUIPage();
00208         return true;
00209     }    
00210     
00211     if(touchAreaIndex == GAS_CHANNEL_DAC_AND_ADC_SET_DAC_VALUE_BUTTON) {
00212         SetGasChannelDACValue(channelSelection, GuiVar_gasChannelDAC_DACValue);
00213         return true;
00214     }    
00215     
00216     if(touchAreaIndex == GAS_CHANNEL_DAC_AND_ADC_DAC_VALUE_EDIT) {
00217         NumericKeypadPageHandler* numericKeypadPageHandler = NumericKeypadPageHandler::GetInstance(usbDevice, usbHostGC);
00218         if(numericKeypadPageHandler != NULL) {
00219             numericKeypadPageHandler->StartEditing(GuiVar_gasChannelDAC_DACValue);
00220             numericKeypadPageHandler->SetEasyGUIVariableToEdit(GuiVar_gasChannelDAC_DACValue);
00221             numericKeypadPageHandler->SetEasyGUICallingPage(GuiStruct_GasChannelDACAndADCPage_Def);
00222             numericKeypadPageHandler->SetEditVariableRange(minimumDACValue, maximumDACValue);
00223             numericKeypadPageHandler->SetEditVariableName("DAC");
00224             numericKeypadPageHandler->DisplayEasyGUIPage();
00225         }
00226     }
00227 
00228     // 'else' - none of the above
00229     return false;
00230 }
00231 
00232 
00233 /*
00234     (Re)display the easyGUI 'GasChannelDACAndADCPage' -
00235     e.g. after the caller has updated one or more of the easyGUI variables
00236     included in the page, and wants to display the new value to the user.
00237     
00238     No arguments, no return code
00239 */
00240 void GasChannelDACAndADCPageHandler::UpdateEasyGUIPage(void)
00241 {
00242     GetGCStatusLoop *getGCStatusLoop = GetGCStatusLoop::GetInstance();
00243     
00244     if(getGCStatusLoop != NULL) {
00245         // The GasChannelDACAndADC page has a status rectangle for the gas - 
00246         // GetGCStatusLoop can display this, we cannot
00247         getGCStatusLoop->ForceUpdateOfGasChannelDACAndADCPage();
00248     }
00249 }
00250 
00251 
00252 /*
00253     Caller is telling us it is about to display the easyGUI 'GasChannelDACAndADCPage',
00254     and that we should do whatever we have to do to get it ready,
00255     before the caller displays it.
00256     
00257     No arguments, no return code
00258 */
00259 void GasChannelDACAndADCPageHandler::DisplayingEasyGUIPage(void)
00260 {
00261     ReadGasChannelSelectionFromQSPISettings();
00262     
00263     // Make both fields grey - text on page tells user what to do, no need to show them which one is active
00264     GuiVar_gasChannelDAC_DACValueBackgroundColour = inactiveFieldBackgroundColour; // = activeFieldBackgroundColour;    
00265     GuiVar_gasChannelDAC_ADCValueBackgroundColour = inactiveFieldBackgroundColour;
00266     
00267     GetGasChannelADCValue(channelSelection, GuiVar_gasChannelDAC_ADCValue);
00268 }
00269 
00270 
00271 /*
00272     Gets the ADC value for the specified gas channel, as a null-terminated string
00273     
00274     Arguments: the channel number
00275                pointer to a buffer to contain the ADC value
00276                
00277     Returns true on success, false on error
00278 */
00279 bool GasChannelDACAndADCPageHandler::GetGasChannelADCValue(int channel, char* buffer)
00280 {
00281     char cmd[20];
00282     sprintf(cmd, "QGA%1d", channel);
00283     
00284     char response[50];
00285     while(usbHostGC->ExecutingSetDeviceReport()) {}
00286     usbHostGC->SetDeviceReport(usbDevice, cmd, response);
00287 //#define DEBUG_PRINTS_HERE
00288 #ifdef DEBUG_PRINTS_HERE
00289 char dbg[100];
00290 sprintf(dbg, "GetGasChannADC %s %s", cmd, response);
00291 SpecialDebugPrint(dbg, 6, 300);
00292 #undef DEBUG_PRINTS_HERE
00293 #endif
00294     // We expect a response like this: "DGAnnnnn", where nnnnn (5 digits) is the ADC value,
00295     // or "EPKT" if something went wrong
00296     if(response[0] == 'E') {
00297         // Assume "EPKT"
00298         return false;
00299     }
00300     
00301     //Ensure null terminator
00302     response[8] = '\0';
00303     
00304     // Ignore leading zeroes - but make sure we leave the final digit, whether zero or not
00305     int startIndex;
00306     for(startIndex = 3; startIndex < 7; ++startIndex) {
00307         if(response[startIndex] != '0') {
00308             break;
00309         }
00310     }
00311     
00312     strcpy(buffer, &response[startIndex]);
00313 
00314     return true;
00315 }
00316 
00317 
00318 /*
00319     Sets the DAC value for the specified gas channel, as a null-terminated string
00320     
00321     Arguments: the channel number
00322                pointer to a buffer that contains the new DAC value, as a null-terminated string
00323                
00324     Returns true on success, false on error
00325 */
00326 bool GasChannelDACAndADCPageHandler::SetGasChannelDACValue(int channel, char* buffer)
00327 {
00328     char command[20];
00329     sprintf(command, "SGD%1d", channel);
00330     
00331     int startIndex = 8 - strlen(buffer);
00332     int index = 4;
00333     while(index < startIndex) {
00334         command[index++] = '0';
00335     }
00336     int bufferIndex = 0;
00337     while(index < 8) {
00338         command[index++] = buffer[bufferIndex++];
00339     }
00340     command[8] = '\0';
00341 
00342     char response[50];
00343     while(usbHostGC->ExecutingSetDeviceReport()) {}
00344     usbHostGC->SetDeviceReport(usbDevice, command, response);
00345 //#define DEBUG_PRINTS_HERE
00346 #ifdef DEBUG_PRINTS_HERE
00347 char dbg[100];
00348 sprintf(dbg, "SetGasChannDAC %s %s", command, response);
00349 SpecialDebugPrint(dbg, 6, 300);
00350 #undef DEBUG_PRINTS_HERE
00351 #endif
00352     // We expect a "DACK" response, or "DNAK" or "EPKT" if something went wrong
00353     if((response[0] == 'E') || (response [1] == 'N')) { // "EPKT" or "DNAK"
00354         return false;
00355     }
00356     
00357     return true;
00358 }
00359