emwin GUI_Init()  takes 10 seconds to complete!

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
WiFl_2253191
Level 2
Level 2

The emWin library requires running GUI_Init() before calling any other GUI functions, but it takes 10 whole seconds to complete!  This product cannot be released to the public until this bug is solved.

   

When I pause the debugger, I see the call stack is
main()
GUI_Init()     <- emWin function, no source
LCD_Init()     <- emWin function, no source
LCD_FillRect()     <- emWin function, no source
...      <- more emWin functions, no source

And the specific paused instruction is a Cypress generated function, LCD_1_Write, with an incrementing value (to fill the rectangle)
LCD_1_Write( 632341, 0)
LCD_1_Write( 632342, 0)
LCD_1_Write( 632343, 0)
etc.

   

Does anyone else have this problem?   I don't know why it's filling the rectangle (I assume it's clearing the background, but I don't need that "help" and it shouldn't take 10 seconds to clear the screen buffers).  I am using virtual screens in external RAM (480x272 LCD with 8 virtual screens).

   

Does anyone have any guesses?

   

Thanks!

0 Likes
1 Solution
WiFl_2253191
Level 2
Level 2

In case anyone else runs into this problem;  I found a workaround.

   

The problem is that the Segger function, GUI_Init(), writes background color to the entire screen buffer area.  If you only have one screen buffer, then it's not a big problem (~1 second delay), but if you're using external RAM and several virtual screens, this adds up to a very long delay (~10 seconds for our 8 virtual screens at 480x272).

   

Although we don't have access to the GUI_Init function, we can access the source code in the driver file, GUIDRV_Control.c.  Here, you can add a couple lines of code to skip the fill rectangle operation as appropriate.

   

I just made it skip any rectangles that are larger than the screen height.

   

static void _FillRect(GUI_DEVICE * pDevice, int x0, int y0, int x1, int y1) {
  if( (y1-y0) > LCD_HEIGHT )  // Ignore rectangles larger than screen height to avoid long init times.
    return;
  for (; y0 <= y1; y0++) {
    _DrawHLine(pDevice, x0, y0, x1);
  }
}

   


You could also add a flag variable (like "guiInitFinished") that makes the function exit immediately until you set the flag.

View solution in original post

0 Likes
1 Reply
WiFl_2253191
Level 2
Level 2

In case anyone else runs into this problem;  I found a workaround.

   

The problem is that the Segger function, GUI_Init(), writes background color to the entire screen buffer area.  If you only have one screen buffer, then it's not a big problem (~1 second delay), but if you're using external RAM and several virtual screens, this adds up to a very long delay (~10 seconds for our 8 virtual screens at 480x272).

   

Although we don't have access to the GUI_Init function, we can access the source code in the driver file, GUIDRV_Control.c.  Here, you can add a couple lines of code to skip the fill rectangle operation as appropriate.

   

I just made it skip any rectangles that are larger than the screen height.

   

static void _FillRect(GUI_DEVICE * pDevice, int x0, int y0, int x1, int y1) {
  if( (y1-y0) > LCD_HEIGHT )  // Ignore rectangles larger than screen height to avoid long init times.
    return;
  for (; y0 <= y1; y0++) {
    _DrawHLine(pDevice, x0, y0, x1);
  }
}

   


You could also add a flag variable (like "guiInitFinished") that makes the function exit immediately until you set the flag.

0 Likes