Repository for import to local machine

Dependencies:   DMBasicGUI DMSupport

Revision:
0:47c880c1463d
Child:
1:a5258871b33d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Wed Jan 13 13:17:05 2016 +0000
@@ -0,0 +1,616 @@
+#include "mbed.h"
+#include "DMBoard.h"
+#include "lpc_swim.h"
+#include "lpc_swim_font.h"
+
+#include <string.h>
+
+#include "GuiLib.h"
+#include "GuiDisplay.h"
+
+#include "USBHostGC.h"
+#include "TouchListener.h"
+#include "TouchPanelPageSelector.h"
+#include "GCHeatControl.h"
+#include "GetGCStatusLoop.h"
+#include "GCComponentStatusColorArea.h"
+#include "EthernetTimerHandler.h"
+
+
+// ** Start of timeout code to guard against multiple presses of the Heat On/Off button **
+//    (which is in the same position as the Abort Run button)
+Timeout heatOnOffTimeout;
+
+bool heatOnOffAvailable = true;
+
+void MakeHeatOnOffAvailableAgain(void)
+{
+    heatOnOffAvailable = true;
+}
+
+void StartHeatOnOffTimeout(void)
+{
+    heatOnOffAvailable = false;
+    heatOnOffTimeout.attach(&MakeHeatOnOffAvailableAgain, 1.0); // Wait 1.0 sec before accepting touches again on Heat On/Off button
+}
+// ** End of Heat On/Off timeout code **
+
+
+// These are 'global' - TouchCallback function, as well as main(), needs to access them
+TouchPanelPageSelectors touchPanelPageSelectors;
+GCHeatControl* theGCHeatControl;
+
+TouchListener* mainTouchListener = NULL;
+GetGCStatusLoop* getGCStatusLoop = NULL;
+
+HomePageGCComponentStatusColorAreas homePageGCComponentStatusColorAreas;
+SingleGCComponentPageStatusColorAreas singleGCComponentPageStatusColorAreas;
+
+EthernetTimerHandler* theEthernetTimerHandler = NULL;
+
+
+GuiConst_INTCOLOR SixteenBitColorValue(GuiConst_INT8U red, GuiConst_INT8U green, GuiConst_INT8U blue)
+{
+    // Make sure we don't have numeric overflow problems during the conversion
+    GuiConst_INT32U red32   = red;
+    GuiConst_INT32U green32 = green;
+    GuiConst_INT32U blue32  = blue;
+    
+    GuiConst_INT32U rgb = (blue32 << 16) | (green32 << 8) | red32;
+    
+    return GuiLib_RgbToPixelColor(rgb);
+}
+
+void DebugPrint(char *stuffToPrint, GuiConst_INT16S X, GuiConst_INT16S Y)
+{
+    char buff[200];
+    
+    const GuiConst_INT16U fontNo = GuiFont_Helv1;
+    
+    GuiDisplay_Lock();
+
+    // (Attempt to) clear previous strings from display
+    sprintf(buff, "                                        ");
+    GuiLib_DrawStr(
+        X,                      //GuiConst_INT16S X,
+        Y,                      //GuiConst_INT16S Y,
+        fontNo,                 //GuiConst_INT16U FontNo,
+        buff,                   //GuiConst_TEXT PrefixLocate *String,
+        GuiLib_ALIGN_LEFT,      //GuiConst_INT8U Alignment, 
+        GuiLib_PS_ON,           //GuiConst_INT8U PsWriting,
+        GuiLib_TRANSPARENT_OFF, //GuiConst_INT8U Transparent,
+        GuiLib_UNDERLINE_OFF,   //GuiConst_INT8U Underlining,
+        0,                      //GuiConst_INT16S BackBoxSizeX,
+        0,                      //GuiConst_INT16S BackBoxSizeY1,
+        0,                      //GuiConst_INT16S BackBoxSizeY2,
+        GuiLib_BBP_NONE,        //GuiConst_INT8U BackBorderPixels,
+        SixteenBitColorValue(0, 0, 0xFF),  //GuiConst_INTCOLOR ForeColor,
+        SixteenBitColorValue(0, 0xFF, 0)   //GuiConst_INTCOLOR BackColor
+    );
+
+    GuiLib_DrawStr(
+        X,                      //GuiConst_INT16S X,
+        Y,                      //GuiConst_INT16S Y,
+        fontNo,                 //GuiConst_INT16U FontNo,
+        stuffToPrint,           //GuiConst_TEXT PrefixLocate *String,
+        GuiLib_ALIGN_LEFT,      //GuiConst_INT8U Alignment, 
+        GuiLib_PS_ON,           //GuiConst_INT8U PsWriting,
+        GuiLib_TRANSPARENT_OFF, //GuiConst_INT8U Transparent,
+        GuiLib_UNDERLINE_OFF,   //GuiConst_INT8U Underlining,
+        0,                      //GuiConst_INT16S BackBoxSizeX,
+        0,                      //GuiConst_INT16S BackBoxSizeY1,
+        0,                      //GuiConst_INT16S BackBoxSizeY2,
+        GuiLib_BBP_NONE,        //GuiConst_INT8U BackBorderPixels,
+        SixteenBitColorValue(0, 0, 0xFF),  //GuiConst_INTCOLOR ForeColor,
+        SixteenBitColorValue(0, 0xFF, 0)   //GuiConst_INTCOLOR BackColor
+    );
+    
+    GuiLib_Refresh();
+
+    GuiDisplay_Unlock();
+}
+
+void EasyGUIDebugPrint(char *stuffToPrint, short X, short Y)
+{
+#define DEBUG_HERE
+#ifdef DEBUG_HERE
+    DebugPrint(stuffToPrint, (GuiConst_INT16S) X, (GuiConst_INT16S) Y);
+#undef DEBUG_HERE
+#endif
+}
+
+void DummyEasyGUIDebugPrint(char *stuffToPrint, short X, short Y)
+{
+    //DebugPrint(stuffToPrint, (GuiConst_INT16S) X, (GuiConst_INT16S) Y);
+}
+
+int DummyDebugFunction(int i)
+{
+    return i^2;
+}
+
+bool GCIsReadyToRun(USBDeviceConnected* usbDevice, USBHostGC* usbHostGC)
+{
+    while(usbHostGC->ExecutingSetDeviceReport()) {}
+
+    char response[50];
+    
+    // Ensure we always have valid chars in the positions we are interested in,
+    // in case we get "DNAK" or "EPKT" back
+    response[6] = '0';
+    response[7] = '0';
+    
+    usbHostGC->SetDeviceReport(usbDevice, "QSTA", response);
+    // We expect a response like "QSTA00nn", where "nn" is the status.
+    // "33" means ready to run, anything else means "not ready"
+    
+    return ((response[6] == '3') && (response[7]== '3'));
+}
+
+void DrawRunButton(bool enabled)
+{
+    // Black if enabled, grey if disabled
+    GuiConst_INTCOLOR buttonColor = (enabled) ? 0 : SixteenBitColorValue(0x80, 0x80, 0x80);
+    
+
+    GuiConst_TEXT *buttonText = "Run";
+
+    // These are hard-coded to match the corresponding definitions in easyGUI
+    // (I have not found a way of getting these values from easyGUI at run time)
+    const GuiConst_INT16S textX1 = 400;
+    const GuiConst_INT16S textY1 = 220;
+    const GuiConst_INT16U textFont = GuiFont_Helv1;
+    
+    const GuiConst_INT16S boxX1 = 338;
+    const GuiConst_INT16S boxY1 = 195;
+    const GuiConst_INT16S boxX2 = 462;
+    const GuiConst_INT16S boxY2 = 235;
+    
+    GuiLib_Box(boxX1, boxY1, boxX2, boxY2, buttonColor);
+    
+    GuiLib_DrawStr(
+        textX1,                 //GuiConst_INT16S X,
+        textY1,                 //GuiConst_INT16S Y,
+        textFont,               //GuiConst_INT16U FontNo,
+        buttonText,             //GuiConst_TEXT PrefixLocate *String,
+        GuiLib_ALIGN_CENTER,    //GuiConst_INT8U Alignment, 
+        GuiLib_PS_ON,           //GuiConst_INT8U PsWriting,
+        GuiLib_TRANSPARENT_ON,  //GuiConst_INT8U Transparent,
+        GuiLib_UNDERLINE_OFF,   //GuiConst_INT8U Underlining,
+        0,                      //GuiConst_INT16S BackBoxSizeX,
+        0,                      //GuiConst_INT16S BackBoxSizeY1,
+        0,                      //GuiConst_INT16S BackBoxSizeY2,
+        GuiLib_BBP_NONE,        //GuiConst_INT8U BackBorderPixels,
+        buttonColor,            //GuiConst_INTCOLOR ForeColor,
+        SixteenBitColorValue(0xFF, 0xFF, 0xFF)   //GuiConst_INTCOLOR BackColor (should be ignored with GuiLib_TRANSPARENT_ON)
+    );
+}
+
+
+void DisplayEasyGuiStructure(int structureIndex, USBDeviceConnected* usbDevice, USBHostGC* usbHostGC)
+{
+    // If required, query the GC to find out if it is ready to run *before* clearing the display -
+    // otherwise the display remains clear while we talk to the GC - causes noticeable flickering
+    bool gcIsReadyToRun = false;
+    if((structureIndex == GuiStruct_HomePage_1) && (usbDevice != NULL) && (usbHostGC != NULL)) {
+        gcIsReadyToRun = GCIsReadyToRun(usbDevice, usbHostGC);
+    }
+    
+    GuiLib_Clear();
+
+    // Note - we draw the status rectangles after GuiLib_Clear - otherwise we wouldn't see the rectangles at all - 
+    // and before GuiLib_ShowScreen - so text, etc, is drawn on top of the rectangles
+    switch(structureIndex) {
+        case GuiStruct_HomePage_1:
+            homePageGCComponentStatusColorAreas.DisplayAll();
+            break;
+        case GuiStruct_ColumnPage1_2:
+        case GuiStruct_ColumnPage2_9:
+        case GuiStruct_ColumnPage3_10:
+            singleGCComponentPageStatusColorAreas.DisplayGCComponentStatus(COLUMN);
+            break;
+        case GuiStruct_InjectorPage1_3:
+            singleGCComponentPageStatusColorAreas.DisplayGCComponentStatus(INJECTOR);
+            break;
+        case GuiStruct_DetectorPage1_4:
+            singleGCComponentPageStatusColorAreas.DisplayGCComponentStatus(DETECTOR);
+            break;
+        case GuiStruct_GasPage1_6:
+            singleGCComponentPageStatusColorAreas.DisplayGCComponentStatus(GAS);
+            break;
+        default: // Don't need to display status rectangle for this page
+            break;
+    }
+            
+    GuiLib_ShowScreen(structureIndex, GuiLib_NO_CURSOR, GuiLib_RESET_AUTO_REDRAW);
+    
+    // But draw the run button, if required, on top of the fixed part of the home page
+    if(structureIndex == GuiStruct_HomePage_1) {
+        DrawRunButton(gcIsReadyToRun);
+    }
+    
+    GuiLib_Refresh();
+#define DEBUG_HERE
+#ifdef DEBUG_HERE
+    char dbg[100];
+    sprintf(dbg, "After GuiLib_Refresh main 1");
+    EasyGUIDebugPrint(dbg, 100, 100);
+#undef DEBUG_HERE
+#endif
+    
+    if(getGCStatusLoop != NULL) {
+        getGCStatusLoop->SetCurrentPage(structureIndex);
+    }
+}
+
+void DrawErrorMessage(char *msg)
+{
+    const GuiConst_INT16U fontNo = GuiFont_Helv1;
+    
+    GuiLib_DrawStr(
+        90,                     //GuiConst_INT16S X,
+        240,                    //GuiConst_INT16S Y,
+        fontNo,                 //GuiConst_INT16U FontNo,
+        msg,                    //GuiConst_TEXT PrefixLocate *String,
+        GuiLib_ALIGN_LEFT,      //GuiConst_INT8U Alignment, 
+        GuiLib_PS_ON,           //GuiConst_INT8U PsWriting,
+        GuiLib_TRANSPARENT_OFF, //GuiConst_INT8U Transparent,
+        GuiLib_UNDERLINE_OFF,   //GuiConst_INT8U Underlining,
+        0,                      //GuiConst_INT16S BackBoxSizeX,
+        0,                      //GuiConst_INT16S BackBoxSizeY1,
+        0,                      //GuiConst_INT16S BackBoxSizeY2,
+        GuiLib_BBP_NONE,        //GuiConst_INT8U BackBorderPixels,
+        SixteenBitColorValue(0, 0, 0xFF),  //GuiConst_INTCOLOR ForeColor,
+        SixteenBitColorValue(0, 0xFF, 0)   //GuiConst_INTCOLOR BackColor
+    ); 
+}
+
+void UpdateHeatOnOffEasyGuiVariable(void)
+{
+    // Note that the easyGUI variable is not the current status of the heat on the GC,
+    // but the command to toggle its current state
+    if(theGCHeatControl != NULL) {
+        if(theGCHeatControl->IsHeatOn()) {
+            strcpy(GuiVar_heatOnOffCommand, "Heat Off");
+        } else {
+            strcpy(GuiVar_heatOnOffCommand, "Heat On");
+        }
+    }
+}
+
+bool StartGCRun(USBDeviceConnected* usbDevice, USBHostGC* usbHostGC)
+{
+    while(usbHostGC->ExecutingSetDeviceReport()) {}
+
+    char response[50];
+    usbHostGC->SetDeviceReport(usbDevice, "CRUN", response);
+    // We expect a response like this: "DACK" for success, "DNAK" for failure
+    
+#define DEBUG_HERE
+#ifdef DEBUG_HERE
+    char dbg[100];
+    sprintf(dbg, "CRUN returned %s", response);
+    EasyGUIDebugPrint(dbg, 100, 150);    
+#endif
+#undef DEBUG_HERE
+
+    return (response[1] == 'A');
+}
+
+bool StopGCRun(USBDeviceConnected* usbDevice, USBHostGC* usbHostGC)
+{
+    while(usbHostGC->ExecutingSetDeviceReport()) {}
+
+    char response[50];
+// TODO: Find out which is the correct command here
+//    char *cmd = "CSTP";
+    char *cmd = "CABT";
+    usbHostGC->SetDeviceReport(usbDevice, cmd, response);
+    // We expect a response like this: "DACK" for success, "DNAK" for failure
+    
+#define DEBUG_HERE
+#ifdef DEBUG_HERE
+    char dbg[100];
+    sprintf(dbg, "%s returned %s", cmd, response);
+    EasyGUIDebugPrint(dbg, 100, 150);    
+#endif
+#undef DEBUG_HERE
+    
+    return (response[1] == 'A');
+}
+
+bool ExitGCStandbyMode(USBDeviceConnected* usbDevice, USBHostGC* usbHostGC)
+{
+    while(usbHostGC->ExecutingSetDeviceReport()) {}
+
+    char response[50];
+    usbHostGC->SetDeviceReport(usbDevice, "CDIS", response);
+    // We expect a response like this: "DACK" for success, "DNAK" for failure
+    
+    char dbg[100];
+    sprintf(dbg, "CDIS returned %s", response);
+    EasyGUIDebugPrint(dbg, 100, 150);   
+    
+    if(getGCStatusLoop != NULL) {
+        getGCStatusLoop->ExitedGCStandbyMode();
+    }
+    
+    return (response[1] == 'A');
+}
+
+bool ClearGCErrors(USBDeviceConnected* usbDevice, USBHostGC* usbHostGC)
+{
+    while(usbHostGC->ExecutingSetDeviceReport()) {}
+
+    char response[50];
+    usbHostGC->SetDeviceReport(usbDevice, "CCLR", response);
+    // We expect a response like this: "DACK" for success, "DNAK" for failure
+    
+    char dbg[100];
+    sprintf(dbg, "CCLR returned %s", response);
+    EasyGUIDebugPrint(dbg, 100, 150);   
+    
+    return (response[1] == 'A');
+}
+
+void TouchCallback(touch_coordinate_t touchCoords, USBDeviceConnected* usbDevice, USBHostGC* usbHostGC, int tickCount, bool newTouch)
+{
+    GuiConst_INT32S touchAreaIndex = GuiLib_TouchCheck((GuiConst_INT16S)touchCoords.x, (GuiConst_INT16S)touchCoords.y);
+
+    if(touchAreaIndex >= 0) {
+        bool dealtWithTouch = false;
+        
+        // page selector?
+        TouchPanelPageSelector* touchPanelPageSelector = touchPanelPageSelectors.GetTouchPanelPageSelector(touchAreaIndex);
+        
+        if( touchPanelPageSelector != NULL) {
+            // Do not keep switching pages if the user keeps 'touching' - 
+            // switch only if he 'lets go', then presses again
+            if(newTouch) {
+                if(touchAreaIndex == 200) {
+                    // Stop run - as well as displaying the home page, do this...
+                    StopGCRun(usbDevice, usbHostGC);
+                }
+                
+                if(touchAreaIndex == 400) {
+                    // Take GC out of standby mode
+                    ExitGCStandbyMode(usbDevice, usbHostGC);
+                }
+                
+                if(touchAreaIndex == 600) {
+                    // Take GC out of error state
+                    ClearGCErrors(usbDevice, usbHostGC);
+                }
+
+                DisplayEasyGuiStructure(touchPanelPageSelector->GetPageNumber(), usbDevice, usbHostGC);
+            }
+            
+            dealtWithTouch = true; // The user touched a page selector, so we have still 'dealt' with this, 
+                                   // whether we had a 'new touch' or not
+                                   
+            if(touchAreaIndex == 200) {
+                // Is in same place as Heat On/Off button
+                StartHeatOnOffTimeout();
+            }
+        }
+        
+        if(!dealtWithTouch) {
+            if(touchAreaIndex == 100) { // Run button
+                if(newTouch) { // As above - do not do this repeatedly - GC does not like it...
+                    if(GCIsReadyToRun(usbDevice, usbHostGC)) {
+                        // Start run - if this works, display the 'Run' page, else do nothing
+                        if(StartGCRun(usbDevice, usbHostGC)) {
+                            DisplayEasyGuiStructure(GuiStruct_RunningPage_7, usbDevice, usbHostGC);
+                        } else {
+                            DrawErrorMessage("*** Run failed to start ***");
+                            
+                            // Give user time to read error, then erase it
+                            Thread::wait(2000);
+                            
+                            DisplayEasyGuiStructure(GuiStruct_HomePage_1, usbDevice, usbHostGC);
+                        }                   
+                    }
+                    // else GC is not ready to run (button should be greyed out) - ignore
+                }
+            
+                dealtWithTouch = true;
+            }
+        }
+
+        if(!dealtWithTouch) {
+            if(touchAreaIndex == 300) { // Heat on/off button
+                if(newTouch) { // As above - do not do this repeatedly - GC does not like it...
+                    if(heatOnOffAvailable) {
+                        if(theGCHeatControl != NULL) {
+                            if(theGCHeatControl->IsHeatOn()) {
+                                theGCHeatControl->TurnHeatOff();
+                            } else {
+                                theGCHeatControl->TurnHeatOn();
+                            }
+                            UpdateHeatOnOffEasyGuiVariable();
+                            
+                            // Make GuiVar_heatOnOffCommand update visible on screen
+                            DisplayEasyGuiStructure(GuiStruct_HomePage_1, usbDevice, usbHostGC);
+        
+                            StartHeatOnOffTimeout();
+                        }
+                    }
+                }
+                                
+                // Whether we changed the heat or not, the user still 'touched' our area,
+                // so no-one else should try and deal with this touch
+                dealtWithTouch = true;
+            }
+        }
+    }
+}
+   
+void SetupUSBGCTouchListener(DMBoard* board, USBDeviceConnected* usbDevice, USBHostGC* usbHostGC)
+{
+    // Note that TouchListener is a singleton - we do not need or want there to be more than one instance of it
+    // (there is only one board, and only one touch panel)
+    mainTouchListener = TouchListener::GetInstance(board->touchPanel(), usbDevice, usbHostGC);
+
+    if(mainTouchListener != NULL) {
+        mainTouchListener->SetTouchCallbackFunction(&TouchCallback);
+
+// Not yet...
+//    mainTouchListener->SetTouchReleasedCallbackFunction(&TouchReleasedCallback);
+//  
+//    mainTouchListener->SetTimerOneSecondCallbackFunction(&TimerOneSecondCallback);
+    }
+}
+
+
+int main()
+{
+  DMBoard::BoardError err;
+  DMBoard* board = &DMBoard::instance();
+  RtosLog* log = board->logger();
+  Display* disp = board->display();
+  
+  do {
+    err = board->init();
+    if (err != DMBoard::Ok) {
+      log->printf("Failed to initialize the board, got error %d\r\n", err);
+      break;
+    }
+    
+    log->printf("\n\nHello World!\n\n");
+    
+    void* fb = disp->allocateFramebuffer();
+    if (fb == NULL) {
+      log->printf("Failed to allocate memory for a frame buffer\r\n");
+      err = DMBoard::MemoryError;
+      break;
+    }
+    
+    
+//    Display::DisplayError disperr = disp->powerUp(fb, Display::Resolution_24bit_rgb888);
+    // Start display in default mode (16-bit) (24-bit uses too much memory)
+    Display::DisplayError disperr = disp->powerUp(fb);
+    if (disperr != Display::DisplayError_Ok) {
+      log->printf("Failed to initialize the display, got error %d\r\n", disperr);
+      break;
+    }
+    
+  } while(false);
+
+  if (err != DMBoard::Ok) {
+    log->printf("\nTERMINATING\n");
+    wait_ms(2000); // allow RtosLog to flush messages
+    mbed_die();
+  }  
+
+  
+  // easyGUI stuff - note function calls require 'extern "C"' in relevant header
+    
+    // Need to set up heat on/off command easyGUI variable 
+    // before we display the home page for the first time - 
+    // but we do not have a heat control object at this point - 
+    // default to 'Heat On'
+    strcpy(GuiVar_heatOnOffCommand, "Heat On");
+    
+    GuiDisplay_Lock();
+    
+    GuiLib_Init();
+  
+    GuiLib_Refresh();
+  
+    DisplayEasyGuiStructure(GuiStruct_HomePage_1, NULL, NULL);
+  
+    GuiLib_Refresh();
+  
+    GuiDisplay_Unlock();
+  
+  
+    // Now the USB 'stuff'
+  
+    USBHost* usbHost = USBHost::getHostInst();
+    USBDeviceConnected* usbDevice;
+    USBHostGC usbHostGC;
+
+    usbDevice = NULL;
+
+    DrawErrorMessage("Waiting for USB device...");
+    
+    // Wait (indefinitely) for a USB device to be connected -
+    // note that, if there is no USB device, we will hang at this point -
+    // there is no timeout
+    while(usbDevice == NULL) {
+        for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; ++i) {
+            usbDevice = usbHost->getDevice(i);
+            
+            if (usbDevice) {
+                break;
+            }
+        }
+    }
+    
+    DrawErrorMessage("                                            ");
+
+    if(usbDevice != NULL) {
+        USB_TYPE enumerateRetVal = usbHost->enumerate(usbDevice, &usbHostGC);
+
+        if (usbHostGC.DeviceIsGC()) {
+            if (usbHostGC.AttachGCDevice(usbDevice)) {
+
+                DrawErrorMessage("Found GC device                                      ");
+                
+
+                SetupUSBGCTouchListener(board, usbDevice, &usbHostGC);
+                
+                DrawErrorMessage("After call to SetupUSBGCTouchListener                ");
+
+
+                getGCStatusLoop = GetGCStatusLoop::GetInstance(usbDevice, &usbHostGC);
+                
+                DrawErrorMessage("After creation of GetGCStatusLoop instance           ");
+                
+                
+                theGCHeatControl = new GCHeatControl(usbDevice, &usbHostGC);
+                
+                UpdateHeatOnOffEasyGuiVariable();
+                
+                DrawErrorMessage("After UpdateHeatOnOffEasyGuiVariable                 ");
+                
+                
+                //theEthernetTimerHandler = EthernetTimerHandler::GetInstance(usbDevice, &usbHostGC);
+                
+                
+                getGCStatusLoop->SetHomePageGCComponentStatusColorAreas(&homePageGCComponentStatusColorAreas);
+                getGCStatusLoop->SetSingleGCComponentPageStatusColorAreas(&singleGCComponentPageStatusColorAreas);
+
+                DrawErrorMessage("Point 1                                              ");
+                
+                getGCStatusLoop->SetupAllEasyGUIVariables();
+
+                DrawErrorMessage("Point 2                                              ");
+                
+                getGCStatusLoop->SetCurrentPage(GuiStruct_HomePage_1);
+                
+                DrawErrorMessage("Point 3                                              ");
+                
+                DisplayEasyGuiStructure(GuiStruct_HomePage_1, usbDevice, &usbHostGC);
+  
+                // Currently, this never returns - but it allows time for the TouchCallback function to be invoked
+                //getGCStatusLoop->MainLoop();
+                getGCStatusLoop->MainLoopWithEthernet();
+                
+                // Should never reach this code - but just in case...
+                delete theGCHeatControl;
+
+            } else {
+                DrawErrorMessage("Failed to attach GC device to host                                ");
+            }
+        } else {
+            DrawErrorMessage("  *** USB device found, is *not* a GC ***                                ");
+        }
+    } else {
+        DrawErrorMessage("  *** No USB device found ***                        ");
+    }
+  
+    while(true) {}
+}
+
+