This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

EK-TM4C123GXL: Widget paint infinite loop

Part Number: EK-TM4C123GXL


I'm trying to make a header widgetStruct that will display several readings like Reference, Feedback, Running/Stopped, Local/Remote control.  I'm still working through all of the details but at this point I'm trying to work out a good way to replace STOPPED/RUNNING (if a change is detected then print a black rectangle first, then print the new status) and I ran into an infinite loop.  Here's my relevant code (or at least what I think is relevant...):

Main


tContext sContext;
bool StartStop=true;
bool StartStop_Last=true;
bool LocalRemote=true;
bool LocalRemote_Last=true;

extern void sample(void);


int main(void)
{

    FPUEnable();
    FPULazyStackingEnable();

    //Initialize system clock to 80MHz
    SysCtlClockSet(SYSCTL_SYSDIV_2|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);

    Kentec320x240x16_SSD2119Init();                         //Screen initialization
    Initialize();
    //
    // Initialize the touch screen driver and have it route its messages to the
    // widget tree.
    //
    TouchScreenInit();
    TouchScreenCallbackSet(WidgetPointerMessage);

    //
    // Add the title block and the previous and next buttons to the widget
    // tree.
    //
    WidgetAdd(WIDGET_ROOT, (tWidget *)&g_sPrevious);
    WidgetAdd(WIDGET_ROOT, (tWidget *)&g_sNext);

    //
    // Add the first panel to the widget tree.
    //
    g_ulPanel = 0;
    WidgetAdd(WIDGET_ROOT, (tWidget *)g_psPanels);
    WidgetAdd(WIDGET_ROOT, (tWidget *)g_psHeader);

    //
    // Issue the initial paint request to the widgets.
    //
    WidgetPaint(WIDGET_ROOT);

    //Enable all interrupts
    IntMasterEnable();

    //Time to start the show!
    // TimerEnable(TIMER2_BASE, TIMER_BOTH);                      //Enable Timer2 for updating the screen
    // TimerEnable(TIMER1_BASE, TIMER_BOTH);                      //Enable Timer1 for taking sample readings

    //
    // Loop forever handling widget messages.
    //
    while(1)
    {
        //
        // Process any messages in the widget message queue.
        //
        WidgetMessageQueueProcess();
    }
}

Canvas definitions for the different parts of the header:

//*****************************************************************************
//
// Canvas for the header info
//
//****************************************************************************


Canvas(g_sStatus, g_psHeader, 0, 0, &g_sKentec320x240x16_SSD2119, 120,
       2, 200, 22, CANVAS_STYLE_APP_DRAWN, 0, 0,
       0, 0, 0, 0, Status);
Canvas(g_sFB, g_psHeader, &g_sStatus, 0, &g_sKentec320x240x16_SSD2119, 80,
       2, 75, 22, CANVAS_STYLE_TEXT|CANVAS_STYLE_TEXT_LEFT, 0, 0,
       ClrRed, &g_sFontCmss16b, "FB:", 0, 0);
Canvas(g_sRef, g_psHeader, &g_sFB, 0, &g_sKentec320x240x16_SSD2119, 2,
       2, 75, 22, CANVAS_STYLE_TEXT|CANVAS_STYLE_TEXT_LEFT, 0, 0,
       ClrRed, &g_sFontCmss16b, "Ref:", 0, 0);

tCanvasWidget for the header canvas structure:


//******************************************************************************
//  Array of canvas widgets for the header.
//
//******************************************************************************


tCanvasWidget g_psHeader[] =
{
 CanvasStruct(0, &g_sFB, &g_sRef, &g_sKentec320x240x16_SSD2119, 0, 0,
              320, 24, CANVAS_STYLE_FILL|CANVAS_STYLE_OUTLINE, ClrBlack, ClrRed, 0, 0, 0, 0, 0),

};

'Status' function for displaying and updating the header bar:


void Status(tWidget *pWidget, tContext *pContext){
    tRectangle sRect_clr;
    GrContextFontSet(pContext, &g_sFontCmss14b);

    GrContextForegroundSet(pContext, ClrRed);
    GrStringDraw(pContext, "STOPPED ", -1,
                 185, 5, 0);

    GrContextForegroundSet(pContext, ClrLawnGreen);
    GrStringDraw(pContext, "LOCAL", -1,
                 270, 5, 0);
    if(StartStop_Last!=StartStop){
        sRect_clr.i16XMin = 180;
        sRect_clr.i16YMin = 2;
        sRect_clr.i16XMax = 250;
        sRect_clr.i16YMax = 20;

        if(StartStop){
            GrContextForegroundSet(pContext, ClrBlack);
            GrRectFill(pContext, &sRect_clr);
            GrContextForegroundSet(pContext, ClrLawnGreen);
            GrStringDraw(pContext, "RUNNING ", -1,
                         185 , 5, 0);

        }

        if(!StartStop){
            GrContextForegroundSet(pContext, ClrBlack);
            GrRectFill(pContext, &sRect_clr);
            GrContextForegroundSet(pContext, ClrRed);
            GrStringDraw(pContext, "STOPPED ", -1,
                         185, 5, 0);
        }
        StartStop_Last=StartStop;
    };
    if(LocalRemote_Last!=LocalRemote){

        if (LocalRemote){
            GrContextForegroundSet(pContext, ClrLawnGreen);
            GrStringDraw(pContext, "LOCAL", -1,
                         270, 5, 0);
        }

        if(!LocalRemote){
            GrContextForegroundSet(pContext, ClrYellow);
            GrStringDraw(pContext, "REMOTE", -1,
                         270, 5, 0);
        }
    };
}

I've discovered that if I move the 'WidgetAdd' statement for the header to above the 'WidgetAdd' statement for the first panel/screen then I do not get this issue of the infinite loop.  I've tried stepping through the disassembly to see what's calling the 'Status' function but I haven't been able to find it.  And if switching the order of the 'WidgetAdd' statements stops the problem then I'm inclined to think that some part of the Stellaris Graphics Library is defaulting to an infinite loop somehow.  

I've confirmed that the panel 1 screen isn't on infinite loop when I switch the order (Header then Panels) because I can get my rising edge detection interrupt and LED firing.  I checked through the vector table to make sure I don't have an interrupt calling the 'Status' function.  I do not, and I don't think it would work to call the widget function from the interrupt table anyways.

If I do switch the order of the 'WidgetAdd' so I don't get an infinite loop then I'm having trouble calling the 'Status' function.  Could anyone give me some tips on the best way to do that?  I've tried to have a timer interrupt trigger a void ScreenUpdate(void) function which will then call the 'Status' function but I've not had any luck with that route.

The rest of my code that isn't show is based entirely on the Lab10 code and I've been slowly building and testing my own widgets and panels.

Thanks