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.

STRANGE DM6437 VPBE LCD VIDWIN0XL PROBLEM

Other Parts Discussed in Thread: TMS320DM6437

 

Hello,

I am driving an Optrex T-51750GD065J-LW-AON LCD 640x480 progressive display using the TMS320DM6437 VPBE and successfully displaying a stable RGB888 video window 0 on the the LCD panel. The problem I am having is that the window appears to have TWICE the width that I specify in the VIDWIN0XL register.

A secondary problem that I am noticing is that the VPBE appears to be reading/displaying TWICE as much data from the DDR that it should (640x480*3/2 instead of 640x480*3/4 bytes). My VIDWIN0OFST is set to (640*3)/32 which I think is correct. If I set it to ((640/2)*3)/32 it seems work though.

The GEL code is below.

This is the procedure I follow:

1) I power cycle and I connect to the DSP via the XDS510. The target hardware is based on the Davinci TMS320DM6437 EVM so the standard GEL file supplied with the examples configures the PLLs, PINMUX etc...

2) I clear the video window 0 memory with Clear_VPBE_frame1(). I am displaying RGB888 so I clear at least 640*480*3 bytes.

3) I call Config_VPBE_pins()  to configure the PINMUX for my RGB666 LCD interface. The DSP needs to be the master and generate RGB666 data, VD, HD, OE and CLK.

4) I call Config_VPBE_LCD() which displays a stable colour video window 0 on the LCD with the correct height but with TWICE the specified width.

If I monitor the LCD OE and one of the LCD RGB666 colour lines with an oscilloscope with video winodow 0 displayed, I can show that the DSP is generating a window that is twice the width that is specified in the VIDWIN0XL register. With VIDWIN0XL set to 160, I get a 320 pixel wide window.

I have monitored the LCD signals and am happy that I meet all the LCD datasheet timings and are within the specified limits.

I would appreciate any help.

Many thanks in advance

Marcos

Electronics/software design engineer

 

hotmenu
Config_VPBE_LCD()
{

    /* Enable clocks to VPBE */
    *VPSS_CLKCTL &= ~(3 << CLKCTL_MUXSEL_SHIFT);
    *VPSS_CLKCTL |= ((0 << CLKCTL_MUXSEL_SHIFT) |
                     _BV(CLKCTL_DACCLKEN_SHIFT) |
                     _BV(CLKCTL_VENCLKEN_SHIFT));

    /* LCD Non-standard and Progressive timings */
    *VPBE_VMOD = 0;

    *VPBE_HSPLS = 8;
    *VPBE_VSPLS = 5;

    *VPBE_HINT = 12 + 640 + 200 - 1;
    *VPBE_HSTART = 12;
    *VPBE_HVALID = 640;

    *VPBE_VINT = 12 + 480 + 2 - 1;
    *VPBE_VSTART = 12;
    *VPBE_VVALID = 480;

    *VPBE_HSDLY = 0;
    *VPBE_VSDLY = 0;

    /* DCLK */
    *VPBE_DCLKCTL = (1 << DCLKCTL_DCKPW_SHIFT) |
                      _BV(DCLKCTL_DCKEC_SHIFT);
    *VPBE_DCLKPTN0 = 0x00000003;
    *VPBE_DCLKPTN1 = 0x00000000;
    *VPBE_DCLKPTN2 = 0x00000000;
    *VPBE_DCLKPTN3 = 0x00000000;
    *VPBE_DCLKPTN0A = 0x00000003;
    *VPBE_DCLKPTN1A = 0x00000000;
    *VPBE_DCLKPTN2A = 0x00000000;
    *VPBE_DCLKPTN3A = 0x00000000;

    /* Enable vertical and horizontal out syncs */
    *VPBE_SYNCCTL |= 0x00000003;

    /* Enable digital output */
    *VPBE_VIDCTL = (0 << VIDCTL_DOMD_SHIFT) |
                   _BV(VIDCTL_VCLKE_SHIFT);

    *VPBE_LCDOUT = _BV(LCDOUT_OEE_SHIFT);

    /* Setup window */
    *VPBE_BASEPX = 0;
    *VPBE_BASEPY = 12;

    /* Win 0 */
    *VPBE_VIDWIN0XP = 0;
    *VPBE_VIDWIN0YP = 0;
    *VPBE_VIDWIN0XL = 160;
    *VPBE_VIDWIN0YL = 480;

    *VPBE_VIDWIN0ADR = 0x81000000;
    *VPBE_PPVWIN0ADR = 0x81000000;
    *VPBE_VIDWIN0OFST = (640*3)/32;

    /* RGB888 */
    *VPBE_MISCCTL = _BV(MISCCTL_RGBEN_SHIFT);

    *VPBE_VIDWINMD = _BV(VIDWINMD_VFF0_SHIFT) |
                     _BV(VIDWINMD_ACT0_SHIFT);

    /* OSD 0/1 */
    *VPBE_OSDWIN0MD = 0;
    *VPBE_OSDWIN1MD = 0;

    /* LCD Non-standard and Progressive timings */
    *VPBE_VMOD = (_BV(VMOD_VMD_SHIFT) | _BV(VMOD_VENC_SHIFT));

}

hotmenu
Clear_VPBE_frame1()
{
    /* Fill buffer */
    GEL_MemoryFill(0x81000000, 0, (640 * 480 *3) /4, 0x7F7F7F7F, 0x12);
}

hotmenu
Config_VPBE_pins()
{

    /* Setup pins for VPBE */
    *PINMUX0 &= ~((7 << PINMUX0_RGBSEL_SHIFT) |
                  (7 << PINMUX0_AEM_SHIFT) |
                  (1 << PINMUX0_VPBECKEN_SHIFT)    |
                  (3 << PINMUX0_VENCSEL_SHIFT) |
                  (3 << PINMUX0_CS3SEL_SHIFT) |
                  (3 << PINMUX0_CS4SEL_SHIFT) |
                  (3 << PINMUX0_CS5SEL_SHIFT));

    *PINMUX0 |=  ((2 << PINMUX0_RGBSEL_SHIFT) |
                  (2 << PINMUX0_VENCSEL_SHIFT) |
                  (2 << PINMUX0_CS3SEL_SHIFT) |
                  (2 << PINMUX0_CS4SEL_SHIFT) |
                  (2 << PINMUX0_CS5SEL_SHIFT));

    *PINMUX1 &= ~(7 << PINMUX1_HOSTBK_SHIFT);


    *VPSS_CLKCTL &= ~(3 << CLKCTL_MUXSEL_SHIFT);
    *VPSS_CLKCTL |= ((0 << CLKCTL_MUXSEL_SHIFT) |
                     _BV(CLKCTL_VENCLKEN_SHIFT));

}

  • Hi,

    I think your OFST is correct.

    Could you please try varying the setting of VPBE_DCLKCTL and VPBE_DCLKPTN0?

    Moreover, could you please also try using YUV422 data and set OFST to 640*2/32? Just to quickly see if the original problem is still there?

  • Hi Paul,

    Thank you for looking at my code and for your reply. It confirms there is some sense in what I am trying to do! ;-)

    1) I cleared MISCCCTL.RGBEN to enable YUV422 and changed VIDWIN0OFST to (620*2)/32. I also "cleared" (640 * 480 * 2) /4 of my frame memory with a "fixed" pattern.

    I can still see that the width of the window is twice what is written to VIDWIN0XL. I can also still see that the VPBE is displaying twice the amount of data that it should as the bottom half of the display is showing uninitialised memory.

    2) I then tried playing with the VPBE_DCLKCTL and VPBE_DCLKPTN0 registers. These registers divide the DCLK using a mask (DCKEC) and mask width (DCKPW).

    The value pairs (DCKPW, DCLKPTN0) of (1, 3), (3, F), (7, FF) maintain a stable LCD image. This makes sense because my display supports a DCLK 20-30MHz with the default 27MHz being just right. The clock "thinning" seems to work as described in the datasheet. but it does change/fix the problem.

    No luck yet but I can to try out other ideas.

    Marcos

  • Marcos,

    Just read your original email again, I am confused here.

    you mentioned "A secondary problem that I am noticing is that the VPBE appears to be reading/displaying TWICE as much data from the DDR that it should (640x480*3/2 instead of 640x480*3/4 bytes).", shouldn't it be 640x480x3 bytes instead if you are displaying 640x480?

     

    Why do you have VIDWIN0XL =160? are you displying a 160x480 VIDWIN0? if so, please try OFST = 160x3/32.

    At the moment, I don't have any other suggestion. I will create a testcase and try it out myself, and will let you know -- however it might take a short while before I can get to this. If you've made any process, please share as well.

     

  • Paul,

    Sorry for the confusion. I meant to say: A secondary problem that I am noticing is that the VPBE appears to be reading/displaying/accessing TWICE the frame memory area in DDR that it should (2*640x480*3 bytes instead of  640x480*3 bytes).

    Yes, the  image pointed by VIDWIN0ADR is RGB888 640x480 but I am displaying a window 0 of 160x480. My understanding is that VIDWIN0OFST refers to the size of 1 line (640*1*3) of the image pointed by VIDWIN0ADR and that VIDWIN0XL is independent controlling the displayed window width. Are you saying that  VIDWIN0OFST must be (VIDWIN0XL*3/32) for RGB888? My experimental observations do not support this because I can generate a test image with 11 vertical colour bars and change VIDWIN0XL very slightly from 160 to say 162 or 158 keeping VIDWIN0OFST constant and I can see the window width change slightly as expected on the LCD without any corruption of the displayed test image bars. This seems to suggest VIDWIN0XL is independent of VIDWIN0OFST.

    I just looked again in SPRU95A "Video Processing Back End" and it says in page 50 under "DDR offsets":

    "The offset registers (Table 20) specify the address offset between each horizontal line of display data.
    Since this is independent of the window display size, this allows a subset of an image to be displayed. The
    offset is in units of 32 bytes."

    I changed OFST to 160x3/32 keeping VIDWIN0XL =160 but my test image bars become corrupted.


    Thanks and please keep the suggestions coming!

    Marcos

  • Marcos,

    The document is correct. Sorry about the confusion.

    OFST shouldn't have anything to do w/ final display size out of the VENC LCD controller. It's merely defining how far two lines are apart in memory buffer.

    For example, if are displaying 160x480, and your buffer is 160x480x(number bytes per pixel) as well, then your OFST should be 160x(number bytes per pixel)/32. However, if your buffer is 640x480x(number bytes per pixel) and you are displaying a vertical stripe of 160x480, then your OFST will be 640x(number bytes per pixel)/32.

    If you are displaying vertical stirpes of an actual 640x480 image, then you should use the 640xno. bytes/32.

     

    Now, back to our original problem. Let me try it out and get back to you, this might take some time though. In your original email, you mentioned

    Marcos Agra-Trillo said:
    ((640/2)*3)/32 

    , does it solve all the problem you are seeing?

  • Hi Paul,

    Setting the offset to ((640/2)*3)/32 does appear to solve the secondary problem that I am seeing where the
    VPBE appears to be reading/displaying/accessing TWICE the frame memory area in DDR that it should. The
    primary problem where the window width 0 is twice the value specified in VIDWIN0XL is not affected.

    I think in both problems are related by the halving (1/2) as the following "appears" to work in RGB888:

    VIDWIN0XL = (1/2)*DESIDED_WIN0_WIDTH
    VIDWIN0OFST = (1/2)*FRAME_WIDTH*FRAME_HEIGHT*3

    I cannot account for the (1/2) but it sounds perhaps like an internal clocking problem or subtle clock setting that is
    not quite right.

    Let me know if you find anything.

    Many thanks
    Marcos

  • Found it. please try OSD_VIDWINMD =  0x0001;


  • Paul,

    Just a small query about OSD_VIDWINMD=0x0001. Are you refering to VIDWINMD or OSDWIN0MD/OSDWIN1MD? I should be able to try it out today and let you know.

    Many thanks for getting back to me.

    Marcos

     

  • Paul,

    I tried it out and setting VIDWINMD to 1 (Field mode) instead of 3 (Frame mode) seems to fix the secondary problem where the VENC was accessing twice the video memory it should. It is now showing the test frame correctly on the vertical direction but the video window 0 width is still twice as width specified in VIDWIN0XL.

    Must be a obscure bit somewhere that is causing this problem!

    Many thanks
    Marcos

  • Marcos, this is something that I tried out before coming with the above recommendation. Please have a look at my init. This was done on another device which has almost identical VPBE and DM6437

     

        VENC_SYNCCTL = 0xf; // Set HSYNC, VSYNC as active low
        VENC_VIOCTL = 0x1001;  // HSYNC, VSYNC as outputs

        VDAC_CONFIG         = 0x081141CF;   // Take DACs out of power down mode
        VPSS_CLKCTL         = 0x0000001a;   // Enable DAC and VENC clock, both at 27 MHz
                                            // Select EXTCLK as video clock source
        VPSS_VPBE_CLK_CTRL  = 0x00000011;   // Select enc_clk*1, turn on VPBE clk
     VENC_CLKCTL         = 0x00000011;   // Enable venc & digital LCD clock

        /* Video window parameters, want 480x272 in a 525x285 pixel frame */
        VENC_SYNCCTL =  0x000f;
        VENC_LCDOUT =   0x0001;


        VENC_VSPLS =         6;
        VENC_VSTART =        0;
        VENC_VVALID =      272;
        VENC_VINTVL =      285;

        VENC_HSPLS =        20;
        VENC_HSTART =        0;
        VENC_HVALID =      480;
        VENC_HINTVL =      524;


        VENC_DCLKCTL =  0x0800;  // Enable DCLK output
        VENC_DCLKPTN0 = 0x0001;

        VENC_VSDLY =         0;
        VENC_HSDLY =         0;

        /* Video window setup */
        OSD_VIDWIN0OFST = (0x8 << 9) | (30); /* SDRAM start address and offset burst size*/
        OSD_VIDWIN0XL =    480;
        OSD_VIDWIN0YL =    272;
        OSD_BASEPX =         4;
        OSD_BASEPY =         8;
        OSD_RECTCUR =        0;  // Disable cursor
        VENC_OSDCLK0 =       0;
        VENC_OSDCLK1 =       1;


        OSD_VIDWINMD =  0x0001; // Enable video window 0, frame mode
        OSD_OSDWIN0MD = 0x0000; // Disable OSD Window 0, frame mode

        VENC_VIOCTL =   0x6000; // Output VCLK, enable YOUT and COUT as outputs
        VENC_VMOD =     0x0011; // Enable VENC, non-standard timing, progressive
        VENC_VDPRO =    0x0000; // No color bars

  • My frame buffer for my 480x272 LCD as follows:


     for(y=0;y<272; y++)
     {
      for(x=0; x <150; x++)
      {
       pdata[y*480+x]=0x8201*(y%2);
      }


      for(x=150; x <300; x++)
      {
       pdata[y*480+x]=0x0345*(y%2);
      }

      for(x=300; x <400; x++)
      {
       pdata[y*480+x]=0x0ff0;
      }


      for(x=400; x <450; x++)
      {
       pdata[y*480+x]=0x1267;
      }


      for(x=450; x <480; x++)
      {
       pdata[y*480+x]=0x8201*(y%2);
      }
     }