Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: DMBasicGUI DMSupport
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
Generated on Tue Jul 19 2022 00:31:06 by
1.7.2