John Mitchell / lpc4088_displaymodule_GC500_2_5inch

Dependencies:   DMBasicGUI DMSupport

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers DetectorIgnitionHandler.cpp Source File

DetectorIgnitionHandler.cpp

00001 #include "DetectorIgnitionHandler.h"
00002 #include "EasyGUITouchAreaIndices.h"
00003 #include "GetGCStatusLoop.h"
00004 #include "USBHostGCUtilities.h"
00005 
00006 #include <stdio.h>
00007 #include <stdlib.h>
00008 #include <math.h>
00009 #include <time.h>
00010 
00011 #define DRAW_TEXT_ON_IGNITE_BUTTON
00012 //#define PERFORM_FULL_IGNITION_SEQUENCE // not #define'd currently - we display the ignition state on the Detector page anyway
00013 
00014 /*
00015     Passed three 8-bit colour components - red, green and blue.
00016     Returns the corresponding 16-bit colour value (5 bits for red, 6 bits for green, 5 bits for blue).
00017     
00018     Defined in main.cpp
00019 */
00020 extern GuiConst_INTCOLOR SixteenBitColorValue(GuiConst_INT8U red, GuiConst_INT8U green, GuiConst_INT8U blue);
00021 
00022 
00023 /*                      
00024     Note that this class is a singleton - we do not need or want there to be more than one instance of it
00025     (we do not want multiple ignition attempts going on simultaneously, and nor will we show 
00026     more than one easyGUI Detector page to the user at the same time).
00027 */
00028 DetectorIgnitionHandler * DetectorIgnitionHandler::theDetectorIgnitionHandlerInstance = NULL;
00029 
00030 /*
00031     Tell the world whether or not we are currently trying to ignite the detector
00032 */
00033 bool DetectorIgnitionHandler::igniting = false;
00034 
00035 /*
00036     Singleton class - return the one and only instance, first creating it if necessary.
00037 */
00038 DetectorIgnitionHandler * DetectorIgnitionHandler::GetInstance(USBDeviceConnected* newUsbDevice, USBHostGC* newUsbHostGC)
00039 {
00040     if (theDetectorIgnitionHandlerInstance == NULL) {
00041         theDetectorIgnitionHandlerInstance = new DetectorIgnitionHandler(newUsbDevice, newUsbHostGC);
00042     }
00043     
00044     return theDetectorIgnitionHandlerInstance;
00045 }
00046 
00047 /*
00048     Overriden version of the above, that does not take any arguments and does not create the instance 
00049     if it does not already exist.
00050     
00051     Provided for callers that do not have the 'usbDevice' and'usbHostGC' pointers, and just want access 
00052     to the instance if it exists
00053 */
00054 DetectorIgnitionHandler * DetectorIgnitionHandler::GetInstance(void)
00055 {
00056     return theDetectorIgnitionHandlerInstance;
00057 }
00058 
00059 
00060 // Singleton class - private constructor
00061 DetectorIgnitionHandler::DetectorIgnitionHandler(USBDeviceConnected* newUsbDevice, USBHostGC* newUsbHostGC)
00062 {
00063     usbDevice = newUsbDevice;
00064     usbHostGC = newUsbHostGC;
00065 }
00066 
00067 // Private destructor also
00068 DetectorIgnitionHandler::~DetectorIgnitionHandler()
00069 {
00070 }
00071 
00072 
00073 /*
00074     Tells the caller whether or not the specified touch area is the one this class handles
00075     
00076     Args: the index of the touch area in question
00077     
00078     Returns true if this class handles that touch area, false if not
00079 */
00080 bool DetectorIgnitionHandler::TouchAreaIsDetectorIgniteButton(int touchAreaIndex)
00081 {
00082     return (touchAreaIndex == DETECTOR_IGNITE_BUTTON);
00083 }
00084 
00085 
00086 /*
00087     If the touch area is the detector ignite button, deals with it and returns true.
00088     Else returns false.
00089     
00090     Args: the index of the touch area in question
00091     
00092     Returns: true if it dealt with the touch area, false if not
00093 */
00094 bool DetectorIgnitionHandler::DealWithTouch(int touchAreaIndex)
00095 {
00096     if (touchAreaIndex == DETECTOR_IGNITE_BUTTON) {
00097         
00098         // Ignore button press if we are already igniting
00099         if(!igniting) {
00100             PerformIgnitionSequence();
00101         }
00102         
00103         return true;
00104     }
00105     
00106     // 'else' ...
00107     return false;
00108 }
00109 
00110 
00111 /*
00112     The FID and FPD detectors require to be ignited before use. The sequence is: 
00113     
00114         send "CIGN" to the GC
00115         
00116         then poll every 1 second (say) with "QIGN"
00117     
00118     This will return "DIGN0002" while trying to ignite, then "DIGN0003" if lit or "DIGN0001" if failed to light. 
00119     
00120     We indicate the status by displaying text on top of the ignite button.
00121 */
00122 void DetectorIgnitionHandler::PerformIgnitionSequence(void)
00123 {
00124     if(TellGCToIgniteDetector()) {
00125         
00126 #ifdef PERFORM_FULL_IGNITION_SEQUENCE
00127         igniting = true;
00128         
00129 #ifdef DRAW_TEXT_ON_IGNITE_BUTTON
00130         DrawIgnitionLightingText();
00131 #endif
00132             
00133         Thread::wait(1000); // 1 second
00134     
00135         IgnitionState ignitionState = GetDetectorIgnitionState();
00136             
00137         while(ignitionState == LIGHTING) {
00138             
00139             Thread::wait(1000); // 1 second
00140             
00141             ignitionState = GetDetectorIgnitionState();
00142         }
00143         
00144 #ifdef DRAW_TEXT_ON_IGNITE_BUTTON
00145         if(ignitionState == LIT) {
00146             DrawIgnitionLitText();
00147         } else {
00148             // Assume not lit
00149             DrawIgnitionNotLitText();
00150         }
00151 #endif
00152         
00153         igniting = false;
00154 #endif // PERFORM_FULL_IGNITION_SEQUENCE
00155 
00156     }
00157 }
00158 
00159 
00160 /*
00161     As the name implies, sends a command to the GC and returns the response.
00162     
00163     Args: pointer to a buffer containing the command, as a null-terminated string
00164           pointer to a buffer to contain the response, as a null-terminated string
00165           
00166     No return code (it is up to the caller to examine the response to see whether 
00167     the command succeeded or failed)
00168 */
00169 void DetectorIgnitionHandler::SendCommandToGCAndGetResponse(char* command, char* response)
00170 {
00171 #define USE_GC_UTILS // Testing new class
00172 #ifdef USE_GC_UTILS
00173     USBHostGCUtilities::SendCommandToGCAndGetResponse(usbDevice, usbHostGC, command, response);
00174 #else
00175     while(usbHostGC->ExecutingSetDeviceReport()) {}
00176 
00177     usbHostGC->SetDeviceReport(usbDevice, command, response);
00178 #endif // USE_GC_UTILS
00179 }
00180 
00181 
00182 /*
00183     Tells the GC to ignite, i.e. sends it a "CIGN" command
00184     
00185     Returns true if the GC responded with "DACK", false for anything else
00186 */
00187 bool DetectorIgnitionHandler::TellGCToIgniteDetector(void)
00188 {
00189     char response[50];
00190     SendCommandToGCAndGetResponse("CIGN", response);
00191     // We expect a response like this: "DACK" for success, "DNAK" for failure, "EPKT" for error
00192     
00193     return (response[1] == 'A');
00194 }
00195 
00196 
00197 /*
00198     Gets the detector ignition state (not lit, igniting, lit), and returns it 
00199     as a value in the IgnitionState enumeration.
00200     
00201     Args: none
00202           
00203     Returns: the ignition state (not lit, lighting, lit);
00204 */
00205 IgnitionState DetectorIgnitionHandler::GetDetectorIgnitionState(void)
00206 {
00207     char response[50];
00208     SendCommandToGCAndGetResponse("QIGN", response);
00209 
00210     // We expect a response like this: "DIGN0001" for "not lit", 
00211     // "DIGN0002" for "igniting", "DIGN0003" for "lit"
00212     
00213     // Check for "EPKT" first
00214     if(response[0] == 'E') {
00215         return NOT_LIT;
00216     }
00217     
00218     // 'else'...
00219     switch (response[7]) {
00220         case '2': 
00221             return LIGHTING;
00222         case '3': 
00223             return LIT;
00224         default:
00225             return NOT_LIT;
00226     }
00227 }
00228 
00229 
00230 /*
00231     Draws the specified text on top of the Ignite button - i.e. at the bottom of the display, 
00232     in the centre, in the specified colour.
00233     
00234     Args: boolean, true to display the text, false to erase it
00235           pointer to the (null-terminated) text
00236           the foregound (i.e. text) colour
00237           the background colour
00238     
00239     No return code.
00240 */
00241 void DetectorIgnitionHandler::DrawTextOnIgniteButton(char* text, GuiConst_INTCOLOR foreColor, GuiConst_INTCOLOR backColor)
00242 {
00243     const GuiConst_INT16U fontNo = GuiFont_Helv20Bold;
00244     
00245     const GuiConst_INT16S X = 400; // Centre of display
00246     const GuiConst_INT16S Y = 450; // Over the Ignite button
00247     
00248     GuiLib_DrawStr(
00249         X,                      //GuiConst_INT16S X,
00250         Y,                      //GuiConst_INT16S Y,
00251         fontNo,                 //GuiConst_INT16U FontNo,
00252         text,                   //GuiConst_TEXT PrefixLocate *String,
00253         GuiLib_ALIGN_CENTER,    //GuiConst_INT8U Alignment, 
00254         GuiLib_PS_ON,           //GuiConst_INT8U PsWriting,
00255         GuiLib_TRANSPARENT_ON,  //GuiConst_INT8U Transparent,
00256         GuiLib_UNDERLINE_OFF,   //GuiConst_INT8U Underlining,
00257         0,                      //GuiConst_INT16S BackBoxSizeX,
00258         0,                      //GuiConst_INT16S BackBoxSizeY1,
00259         0,                      //GuiConst_INT16S BackBoxSizeY2,
00260         GuiLib_BBP_NONE,        //GuiConst_INT8U BackBorderPixels,
00261         foreColor,              //GuiConst_INTCOLOR ForeColor,
00262         backColor               //GuiConst_INTCOLOR BackColor
00263     ); 
00264 }
00265 
00266 /*
00267     Draws "Lighting" on top of the ignite button, in yellow
00268     
00269     No arguments, no return code
00270 */
00271 void DetectorIgnitionHandler::DrawIgnitionLightingText(void)
00272 {
00273     DrawTextOnIgniteButton("Lighting", SixteenBitColorValue(236, 219, 0), SixteenBitColorValue(0, 0, 0));
00274 }
00275 
00276 /*
00277     Draws "Lit" on top of the ignite button, in green
00278     
00279     No arguments, no return code
00280 */
00281 void DetectorIgnitionHandler::DrawIgnitionLitText(void)
00282 {
00283     DrawTextOnIgniteButton("Lit", SixteenBitColorValue(0, 236, 5), SixteenBitColorValue(0, 0, 0));
00284 }
00285 
00286 /*
00287     Draws "Not Lit" on top of the ignite button, in red
00288     
00289     No arguments, no return code
00290 */
00291 void DetectorIgnitionHandler::DrawIgnitionNotLitText(void)
00292 {
00293     DrawTextOnIgniteButton("Not Lit", SixteenBitColorValue(255, 0, 0), SixteenBitColorValue(0, 0, 0));
00294 }
00295