GUIDRV_Lin update callback?

    This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

    • GUIDRV_Lin update callback?

      Hello,

      I am using emWin to control a small 1 bit OLED (SSD1306) display. I am using the GUIDRV_Lin driver as it is the only one provided in the STemWin package that supports 1 bit/pixel.
      The implementation is rather simple - the LCD driver only supports the init command and GUIDRV_Lin writes directly into the framebuffer. All I have to add is after displaying something (eg write some text), I have to manually copy the contents of the framebuffer to the OLED module via SPI.
      Probably this is not the way GUIDRV_Lin is intended to use, but it is simple and works well enough. Is there a way to automatically call the "copy framebuffer to SPI" routine - eg some callback after a screen update?

      Thanks! Martin
    • Hi,

      No unfortunately there is no such function.

      You could try something like:

      C Source Code

      1. while (1) {
      2. DoneSomething = GUI_Exec();
      3. if (DoneSomething) {
      4. UpdateLCD();
      5. }
      6. }





      The disadvantage is that GUI_Exec() returns also with 1 if emWin has processed other things than drawing like timer or touch input.

      Another solution might be to use the multi buffering API.

      In the function LCD_X_Config() you set the VRAM address like this:

      C Source Code

      1. void LCD_X_Config(void) {
      2. static const U32 _aBufferPTRGUI[] = {
      3. LCD_FRAME_BUFFER0,
      4. LCD_FRAME_BUFFER0,
      5. };
      6. GUI_MULTIBUF_Config(2);
      7. ...
      8. ...
      9. ...
      10. LCD_SetBufferPtrEx(0, (void **)_aBufferPTRGUI);
      11. }
      Display All
      Now emWin "thinks" it has to buffers to be used for multibuffering. and will send the LCD_X_SHOWBUFFER command to the driver callback function. This command will be send as soon as the Window Manager has finished drawing all invalid windows.

      In the function LCD_X_DisplayDriver() you can react on the LCD_X_SHOWBUFFER command and send the data to your lcd:


      C Source Code

      1. case LCD_X_SHOWBUFFER: {
      2. SendData();
      3. break;
      4. }

      If you are not using the Window Manager just surround your drawing operations with GUI_MULTIBUF_Begin() and GUI_MULTIBUF_End(). Like:

      C Source Code

      1. GUI_MULTIBUF_Begin();
      2. YourDrawingOperationA();
      3. YourDrawingOperationB();
      4. YourDrawingOperationC();
      5. YourDrawingOperationD();
      6. GUI_MULTIBUF_End();

      When calling GUI_MULTIBUF_Begin() emWin will perform a copy buffer from the front to the backbuffer. Since you have only one buffer (emWin is just thinking you have two) you might want to set a dummy function for copy buffer. Just to avoid any troubles.

      In LCD_X_Config() add:

      C Source Code

      1. LCD_SetDevFunc(0, LCD_DEVFUNC_COPYBUFFER, DummyCPYBuffer);
      The function does actually nothing:


      C Source Code

      1. static void DummyCPYBuffer(int LayerIndex, int IndexSrc, int IndexDst) {
      2. GUI_USE_PARA(LayerIndex);
      3. GUI_USE_PARA(IndexSrc);
      4. GUI_USE_PARA(IndexDst);
      5. }


      Haven't had the chance to check this on a device like your but it seemed to be working on a STM32F746 Disco.

      Regards,
      Sven
    • Hi,

      my colleague told me that we actually have such a function. I wasn't aware of that.

      Simply call the following function in LCD_X_Config():

      C Source Code

      1. GUI_SetControlHook(UpdateLCD);

      The UpdateLCD() function looks like:

      C Source Code

      1. void UpdateLCD(int LayerIndex, int Cmd) {
      2. GUI_USE_PARA(LayerIndex);
      3. if (Cmd == LCD_CC_UNLOCK) {
      4. SendData();
      5. }
      6. }
      The LCD_CC_LOCK command is send after the Window Manager has drawn the last invalid window.

      It is important that you do NOT use any multibuffering API when using GUI_SetControlHook(). So remove any calls of WM_MULTIBUF_Enable(), GUI_MULTIBUF_Begin()/GUI_MULTIBUF_End() and GUI_MULTIBUF_Config().


      Regards,

      Sven