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.

Bealgebone-Black Framebuffer, Flicker problem !

Hi.

I use ti-processor-sdk-linux-am335x-evm-01.00.00.03 in Beaglebone-Black.

I use directly framebuffer for TFT LCD Display.

But My LCD Display have flicker.

Dual Framebuffer Switching Source.

void LcdFb_Flip ( void )

{

unsigned char PreIndex ;

unsigned long dummy ;

if ( g_LcdFd == -1 )
return ;

PreIndex = g_FBFlipIndex ;
++ g_FBFlipIndex ;
if ( g_FBFlipIndex >= MAX_FB_PAGE )
g_FBFlipIndex = 0 ;

g_FBVar.activate = FB_ACTIVATE_VBL ;       ---------------> Active After VSync Blank Check ?
g_FBVar.xoffset = 0 ;
g_FBVar.yoffset = g_FBFlipIndex * FB_YSIZE ;    -----------------> Y-Offset Location Switching

if ( ioctl ( g_LcdFd, FBIOPAN_DISPLAY, &g_FBVar ) < 0 )
      MessageOut ( 3, "FBIOPAN_DISPLAY run Error !\n" ) ;

g_FBDrawMaped = (unsigned short *)(g_FBMaped + (PreIndex * FB_FRAME_SIZE)) ;  ------------> New Drawing Address
}

I don't know How modify.

Help !

  • Hi,

    You should update only the framebuffer that is not currently being used by the LCD. See this document for LCD usage:

    3681.LCDC.pdf

  • Hi, Biser.

    I  can't understand your recommend.

    I write only the framebuffer area that is not used by the LCD.

    After I write complete, I change th framebuffer area with FB_ACTIVATE_VBL Mode.

    But My Display has Flicker.

    I use FB_ACTIVATE_VBL Mode and yoffset change.

    Correct ?

    My Display has continuously Flicker.

    Help !

  • Have you checked that your display timings are set correctly?
  • Hi, Biser.
    Thank you, Reply.

    My am335x-boneblack.dts file.

    panel {
    compatible = "ti,tilcdc,panel";
    status = "okay";
    pinctrl-names = "default";
    pinctrl-0 = <&lcd_pins_default>;

    panel-info {
    ac-bias = <255>;
    ac-bias-intrpt = <0>;
    dma-burst-sz = <16>;
    bpp = <16>;
    fdd = <0x80>;
    sync-edge = <0>;
    sync-ctrl = <1>;
    raster-order = <0>;
    fifo-th = <0>;
    };

    display-timings {
    native-mode = <&timing0>;
    timing0: 240x320p80 {
    clock-frequency = <7347200>; // Frame Rate : 80Hz
    hactive = <240>;
    vactive = <320>;
    hfront-porch = <10>;
    hback-porch = <20>;
    hsync-len = <10>;
    vback-porch = <2>;
    vfront-porch = <4>;
    vsync-len = <2>;
    hsync-active = <0>;
    vsync-active = <0>;
    };
    };
    };

    My Lcd Drive Source.

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/time.h>
    #include <time.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <sys/ioctl.h>
    #include <sys/mman.h>
    #include <linux/fb.h>

    #include "main.h"
    #include "lcdfb.h"
    #include "devicenet.h"

    //======================================================================================================

    #define MAX_FB_PAGE (unsigned long)2
    #define FB_XSIZE (unsigned long)240
    #define FB_YSIZE (unsigned long)320
    #define FB_BYTEPPIXEL (unsigned long)2
    #define FB_LINEBYTES (unsigned long)480
    #define FB_PIXEL_SIZE (unsigned long)76800
    #define FB_FRAME_SIZE (unsigned long)153600
    #define FB_MMAP_SIZE (unsigned long)307200

    //======================================================================================================

    int g_LcdFd = -1 ;
    void *g_FBMaped = NULL ;
    unsigned short *g_FBDrawMaped = NULL ;
    unsigned char g_FBFlipIndex = 1 ;

    struct fb_var_screeninfo g_FBVar ;

    char g_Power_ControlB_Cmd[8] = { 0xCF, 0x00, 0x00, 0x01, 0xC1, 0x01, 0x30, 0x01 } ;
    char g_Power_Seq_Cmd[10] = { 0xED, 0x00, 0x64, 0x01, 0x03, 0x01, 0x12, 0x01, 0x81, 0x01 } ;
    char g_DT_ControlA_Cmd[8] = { 0xE8, 0x00, 0x85, 0x01, 0x01, 0x01, 0x78, 0x01 } ;
    char g_Power_ControlA_Cmd[12] = { 0xCB, 0x00, 0x39, 0x01, 0x2C, 0x01, 0x00, 0x01, 0x34, 0x01, 0x02, 0x01 } ;
    char g_NoName1_Cmd[4] = { 0xF7, 0x00, 0x20, 0x01 } ;
    char g_DT_ControlC_Cmd[6] = { 0xEA, 0x00, 0x00, 0x01, 0x00, 0x01 } ;
    char g_Power_Control1_Cmd[4] = { 0xC0, 0x00, 0x21, 0x01 } ; // 3.3V
    char g_Power_Control2_Cmd[4] = { 0xC1, 0x00, 0x12, 0x01 } ;
    char g_VCom_Control1_Cmd[6] = { 0xC5, 0x00, 0x4A, 0x01, 0x3D, 0x01 } ;
    char g_VCom_Control2_Cmd[4] = { 0xC7, 0x00, 0x83, 0x01 } ;
    char g_Mem_Control_Cmd[4] = { 0x36, 0x00, 0x08, 0x01 } ;
    char g_Frame_Control_Cmd[6] = { 0xB1, 0x00, 0x00, 0x01, 0x15, 0x01 } ; // 70Hz
    char g_DisFunc_Control_Cmd[10] = { 0xB6, 0x00, 0x0A, 0x01, 0xA2, 0x01, 0x27, 0x01, 0x04, 0x01 } ;
    char g_3Gamma_Disable_Cmd[4] = { 0xF2, 0x00, 0x00, 0x01 } ;
    char g_Gamma_Set_Cmd[4] = { 0x26, 0x00, 0x01, 0x01 } ;
    char g_PosGamma_Set_Cmd[32] = { 0xE0, 0x00, 0x0F, 0x01, 0x09, 0x01, 0x1E, 0x01, 0x07, 0x01, 0x0B, 0x01, 0x01, 0x01, 0x45, 0x01,
    0x6D, 0x01, 0x37, 0x01, 0x08, 0x01, 0x13, 0x01, 0x01, 0x01, 0x06, 0x01, 0x06, 0x01, 0x00, 0x01 } ;
    char g_NegGamma_Set_Cmd[32] = { 0xE1, 0x00, 0x00, 0x01, 0x01, 0x01, 0x18, 0x01, 0x00, 0x01, 0x0D, 0x01, 0x00, 0x01, 0x2A, 0x01,
    0x44, 0x01, 0x44, 0x01, 0x04, 0x01, 0x11, 0x01, 0x0C, 0x01, 0x30, 0x01, 0x34, 0x01, 0x0F, 0x01 } ;
    char g_Pixel_Format_Cmd[4] = { 0x3A, 0x00, 0x55, 0x01 } ;
    char g_RGB_Control_Cmd[4] = { 0xB0, 0x00, 0xC2, 0x01 } ;
    char g_Interface_Control_Cmd[8] = { 0xF6, 0x00, 0x00, 0x01, 0x00, 0x01, 0x06, 0x01 } ;
    char g_ColAddr_Set_Cmd[10] = { 0x2A, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0xEF, 0x01 } ;
    char g_PageAddr_Set_Cmd[10] = { 0x2B, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x3F, 0x01 } ;
    char g_Sleep_Out_Cmd[2] = { 0x11, 0x00 } ;
    char g_Display_On_Cmd[2] = { 0x29, 0x00 } ;
    char g_Mem_Write_Cmd[2] = { 0x2C, 0x00 } ;

    unsigned char g_LcdDrawStep = LCDDRAW_IDLE ;

    //======================================================================================================

    void LcdFb_Flip ( void ) ;
    void LcdFb_Clear ( void ) ;
    void LcdFb_Fill ( unsigned short FillValue ) ;

    //======================================================================================================

    unsigned char LcdFB_init ( void )
    {
    if ( ! Gpio_Init ( 65, 1 ) )
    {
    MessageOut ( 3, "LCD Reset IO Init Fail !\n" ) ;
    return 0 ;
    }
    Gpio_Set ( 65, 1 ) ;
    if ( ! Gpio_Init ( 46, 1 ) )
    {
    MessageOut ( 3, "LCD BackLight IO Init Fail !\n" ) ;
    return 0 ;
    }
    Gpio_Set ( 46, 0 ) ;
    usleep ( 10000 ) ;

    Gpio_Set ( 65, 0 ) ;
    usleep ( 50000 ) ;
    Gpio_Set ( 65, 1 ) ;
    usleep ( 200000 ) ;

    if ( access ( "/dev/fb", F_OK ) )
    {
    MessageOut ( 3, "/dev/fb isn't Exist !\n" ) ;
    return 0 ;
    }

    if ( (g_LcdFd = open ( "/dev/fb", O_RDWR )) < 0 )
    {
    MessageOut ( 3, "/dev/fb can't Access !\n" ) ;
    return 0 ;
    }

    if ( ioctl ( g_LcdFd, FBIOGET_VSCREENINFO, &g_FBVar ) < 0 )
    {
    MessageOut ( 3, "FBIOGET_VSCREENINFO run Error !\n" ) ;
    close ( g_LcdFd ) ;
    g_LcdFd = -1 ;
    return 0 ;
    }

    g_FBVar.activate = FB_ACTIVATE_VBL ;
    g_FBVar.xres = FB_XSIZE ;
    g_FBVar.yres = FB_YSIZE ;
    g_FBVar.xres_virtual = FB_XSIZE ;
    g_FBVar.yres_virtual = FB_YSIZE * MAX_FB_PAGE ;
    g_FBVar.xoffset = 0 ;
    g_FBVar.yoffset = g_FBFlipIndex * FB_YSIZE ; // Start Display Index = 1
    g_FBVar.bits_per_pixel = 16 ;

    if ( ioctl ( g_LcdFd, FBIOPUT_VSCREENINFO, &g_FBVar ) < 0 )
    {
    MessageOut ( 3, "FBIOPUT_VSCREENINFO run Error !\n" ) ;
    close ( g_LcdFd ) ;
    g_LcdFd = -1 ;
    return 0 ;
    }

    if ( ioctl ( g_LcdFd, FBIOPAN_DISPLAY, &g_FBVar ) < 0 )
    {
    MessageOut ( 3, "FBIOPAN_DISPLAY run Error !\n" ) ;
    close ( g_LcdFd ) ;
    g_LcdFd = -1 ;
    return 0 ;
    }

    g_FBMaped = (void *)mmap ( 0,
    FB_MMAP_SIZE,
    PROT_READ | PROT_WRITE,
    MAP_SHARED,
    g_LcdFd,
    0 ) ;
    if ( g_FBMaped < 0 )
    {
    MessageOut ( 3, "MMAP run Error !\n" ) ;
    close ( g_LcdFd ) ;
    g_LcdFd = -1 ;
    return 0 ;
    }

    g_FBDrawMaped = (unsigned short *)g_FBMaped ;
    memset ( g_FBMaped, 0, FB_MMAP_SIZE ) ;

    if ( SPI1_Open ( ) )
    {
    SPI1_Write ( g_Power_ControlB_Cmd, 8 ) ;
    SPI1_Write ( g_Power_Seq_Cmd, 10 ) ;
    SPI1_Write ( g_DT_ControlA_Cmd, 8 ) ;
    SPI1_Write ( g_Power_ControlA_Cmd, 12 ) ;
    SPI1_Write ( g_NoName1_Cmd, 4 ) ;
    SPI1_Write ( g_DT_ControlC_Cmd, 6 ) ;
    SPI1_Write ( g_Power_Control1_Cmd, 4 ) ;
    SPI1_Write ( g_Power_Control2_Cmd, 4 ) ;
    SPI1_Write ( g_VCom_Control1_Cmd, 6 ) ;
    SPI1_Write ( g_VCom_Control2_Cmd, 4 ) ;
    SPI1_Write ( g_Mem_Control_Cmd, 4 ) ;
    SPI1_Write ( g_Frame_Control_Cmd, 6 ) ;
    SPI1_Write ( g_DisFunc_Control_Cmd, 10 ) ;
    SPI1_Write ( g_3Gamma_Disable_Cmd, 4 ) ;
    SPI1_Write ( g_Gamma_Set_Cmd, 4 ) ;
    SPI1_Write ( g_PosGamma_Set_Cmd, 32 ) ;
    SPI1_Write ( g_NegGamma_Set_Cmd, 32 ) ;
    SPI1_Write ( g_Pixel_Format_Cmd, 4 ) ;
    SPI1_Write ( g_RGB_Control_Cmd, 4 ) ;
    SPI1_Write ( g_Interface_Control_Cmd, 8 ) ;
    SPI1_Write ( g_ColAddr_Set_Cmd, 10 ) ;
    SPI1_Write ( g_PageAddr_Set_Cmd, 10 ) ;
    SPI1_Write ( g_Sleep_Out_Cmd, 2 ) ;
    usleep ( 200000 ) ;
    SPI1_Write ( g_Display_On_Cmd, 2 ) ;
    SPI1_Write ( g_Mem_Write_Cmd, 2 ) ;

    SPI1_Close ( ) ;
    }
    else
    {
    MessageOut ( 3, "LCD SPI Init Fail !\n" ) ;
    munmap ( g_FBMaped, FB_MMAP_SIZE ) ;
    close ( g_LcdFd ) ;
    g_LcdFd = -1 ;
    return 0 ;
    }

    MessageOut ( 0, "/dev/fb Open Success !\n" ) ;

    return 1 ;
    }

    void LcdFb_Close ( void )
    {
    if ( g_LcdFd != -1 )
    {
    munmap ( g_FBMaped, FB_MMAP_SIZE ) ;
    close ( g_LcdFd ) ;
    g_LcdFd = -1 ;
    }
    }

    void LcdFb_Flip ( void ) ---------------------------> Framebuffer Flip : Page Change
    {
    unsigned char PreIndex ;

    if ( g_LcdFd == -1 )
    return ;

    PreIndex = g_FBFlipIndex ;
    ++ g_FBFlipIndex ;
    if ( g_FBFlipIndex >= MAX_FB_PAGE )
    g_FBFlipIndex = 0 ;

    g_FBDrawMaped = (unsigned short *)(g_FBMaped + (PreIndex * FB_FRAME_SIZE)) ;

    g_FBVar.activate = FB_ACTIVATE_VBL ;
    g_FBVar.xoffset = 0 ;
    g_FBVar.yoffset = g_FBFlipIndex * FB_YSIZE ;

    if ( ioctl ( g_LcdFd, FBIOPAN_DISPLAY, &g_FBVar ) < 0 )
    MessageOut ( 3, "FBIOPAN_DISPLAY run Error !\n" ) ;
    }

    //===========================================================================================

    void LcdFb_Clear ( void )
    {
    if ( g_LcdFd == -1 )
    return ;

    memset ( (void*)g_FBDrawMaped, 0, FB_FRAME_SIZE ) ;
    }

    void LcdFb_Fill ( unsigned short FillValue )
    {
    unsigned short *sptr ;
    unsigned long i ;

    if ( g_LcdFd == -1 )
    return ;

    sptr = g_FBDrawMaped ;
    for ( i=0;i<FB_PIXEL_SIZE;i++ )
    *sptr ++ = FillValue ;
    }

    //===========================================================================================

    void Lcd_Draw_Proc ( void )
    {
    unsigned long i = 0 ;
    static unsigned short color = 0 ;

    LcdFb_Fill ( color ) ;
    color += 10 ;

    switch ( g_LcdDrawStep )
    {
    case LCDDRAW_IDLE :
    break ;

    }

    while ( i < 50000000 )
    ++ i ;

    LcdFb_Flip ( ) ;
    Gpio_Set ( 46, 1 ) ; // Back-Light On
    }

    Confirm, Please !
  • Hi, Biser.

    Thank you, 

    My Display has not Flicker.

    My Source has mistake.

    New Source.

    void Lcd_Draw_Proc ( void )
    {
    unsigned long i = 0 ;
    static unsigned short color = 0 ;

    while ( i < 5000000 )
    ++ i ;

    LcdFb_Fill ( 0x0000 ) ;
    LcdFb_Fill ( color ) ;
    color += 10 ;

    // No Delay

    LcdFb_Flip ( ) ;
    Gpio_Set ( 46, 1 ) ; // Back-Light On
    }

    Thank you.