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.

Video Dual-DAC Test Mode

Other Parts Discussed in Thread: OMAP3530

Has anyone ever used the display subsystem function where the dual 10-Bit video DAC can be placed in test mode (on OMAP3530)?  Either 10-bit external random data, or 10-bit internal register values can be routed directly to the DAC, bypassing the video encoder.  I am trying to take advantage of the this test mode to route some data and do general processing on the GPU -- the overall platform I am using to do this is the Beagleboard.  I'm also wondering if there are any limitations on which internal registers can be used,and generally, the overall performance of the test mode.

  • The following code should get you there.

    The DSS clocks need to be configured and running first, so just enable any display and it should get you there.

    Call "SetupTV()". This should enable the internal color bar generator and display on the CVBS/S-Video output.

    void InitNTSC( void )
    {
      WritePhysical(VENC_F_CONTROL                         , 0x00000000);
      WritePhysical(VENC_SYNC_CTRL                         , 0x00008040);
      WritePhysical(VENC_VIDOUT_CTRL                       , 0x00000000);
      WritePhysical(VENC_LLEN                              , 0x00000359);
      WritePhysical(VENC_FLENS                             , 0x0000020C);
      WritePhysical(VENC_HFLTR_CTRL                        , 0x00000000);
      WritePhysical(VENC_CC_CARR_WSS_CARR                  , 0x043F0000);
      WritePhysical(VENC_C_PHASE                           , 0x00000000);
      WritePhysical(VENC_GAIN_U                            , 0x00000102);
      WritePhysical(VENC_GAIN_V                            , 0x0000016C);
      WritePhysical(VENC_GAIN_Y                            , 0x0000012F);
      WritePhysical(VENC_BLACK_LEVEL                       , 0x00000043);
      WritePhysical(VENC_BLANK_LEVEL                       , 0x00000038);
      WritePhysical(VENC_X_COLOR                           , 0x00000007);
      WritePhysical(VENC_M_CONTROL                         , 0x00000001);
      WritePhysical(VENC_BSTAMP_WSS_DATA                   , 0x00000038);
      WritePhysical(VENC_S_CARR                            , 0x21F07C1F);
      WritePhysical(VENC_LINE21                            , 0x00000000);
      WritePhysical(VENC_LN_SEL                            , 0x00000015);
      WritePhysical(VENC_L21__WC_CTL                       , 0x00001400);
      WritePhysical(VENC_SAVID_EAVID                       , 0x069300F4);
      WritePhysical(VENC_FLEN_FAL                          , 0x0016020C);
      WritePhysical(VENC_LAL__PHASE_RESET                  , 0x00060107);
      WritePhysical(VENC_HS_INT_START_STOP_X               , 0x008D034E);
      WritePhysical(VENC_HS_EXT_START_STOP_X               , 0x000F0359);
      WritePhysical(VENC_VS_INT_START_X                    , 0x01A00000);
      WritePhysical(VENC_VS_INT_STOP_X__VS_INT_START_Y     , 0x020301A0);
      WritePhysical(VENC_VS_INT_STOP_Y__VS_EXT_START_X     , 0x01AC0024);
      WritePhysical(VENC_VS_EXT_STOP_X__VS_EXT_START_Y     , 0x020D01AC);
      WritePhysical(VENC_VS_EXT_STOP_Y                     , 0x00000006);
      WritePhysical(VENC_AVID_START_STOP_X                 , 0x03480078);
      WritePhysical(VENC_AVID_START_STOP_Y                 , 0x02040024);
      WritePhysical(VENC_FID_INT_START_X__FID_INT_START_Y  , 0x0001008A);
      WritePhysical(VENC_FID_INT_OFFSET_Y__FID_EXT_START_X , 0x01AC0106);
      WritePhysical(VENC_FID_EXT_START_Y__FID_EXT_OFFSET_Y , 0x01060006);
      WritePhysical(VENC_TVDETGP_INT_START_STOP_X          , 0x00140001);
      WritePhysical(VENC_TVDETGP_INT_START_STOP_Y          , 0x00010001);

      WritePhysical(VENC_GEN_CTRL                          , 0x00F90000);

      WritePhysical(VENC_SYNC_CTRL                         , 0x00008000);
      WritePhysical(VENC_F_CONTROL                         , 0x00000000);
    }

    void ResetAndConfigVENC(unsigned char TVConnection)
    {
      // Reset the VENC
      WritePhysical(VENC_F_CONTROL , VENC_RESET_ENCODER);
     
      // wait in a loop till the encoder resets
      while(ReadPhysical(VENC_F_CONTROL) & VENC_RESET_DONE);

      /* Enable the DAC */
      if (TVConnection == CVBS)
      {
        WritePhysical(VENC_OUTPUT_CONTROL                    , 0x0000004A);
        WritePhysical(DSS_CONTROL , ((ReadPhysical(DSS_CONTROL) | DSS_VENC_4X_ENABLE | DSS_DACDEMEN_ENABLE | DSS_VENC_DAC_POWERDN_BGZ) & (~VENC_OUT_SEL)));
      }
      else
      {
        WritePhysical(VENC_OUTPUT_CONTROL                    , 0x0000000d);
        WritePhysical(DSS_CONTROL , ((ReadPhysical(DSS_CONTROL) | DSS_VENC_4X_ENABLE | DSS_DACDEMEN_ENABLE | DSS_VENC_DAC_POWERDN_BGZ) | VENC_OUT_SEL));
      }
     
      // Set VENC output clock as 54 MHz
      WritePhysical(VENC_VIDOUT_CTRL , VENC_54MHx_CLK);
     
      // Resetting the register
      WritePhysical(VENC_SYNC_CTRL , 0x00000000);
     
      // Resetting the register
      WritePhysical(VENC_F_CONTROL , 0x00000000);
     
      // Disable the free running mode of the VENC
      WritePhysical(VENC_SYNC_CTRL , FREE_RUNNING_DISABLE);
     
      // Select Video source as Display controller
      WritePhysical(VENC_F_CONTROL , ENABLE_EXTERNAL_VIDEO);

    }

    void SetNTSCCB()
    {
      WritePhysical(VENC_SYNC_CTRL , 0x00008040); //Free running
      WritePhysical(VENC_F_CONTROL , 0x40);//Internal color bar select
    }

    void SetupTV()
    {
      //Configure the VENC
      ResetAndConfigVENC(SVIDEO);
      InitNTSC();
      SetNTSCCB();
    }

  • This is great ... thank you.

    One follow-up question:  in the section,

    // Set VENC output clock as 54 MHz
      WritePhysical(VENC_VIDOUT_CTRL , VENC_54MHx_CLK);

    In general, can the output clock be set to any speed, or is there a list of selectable choices?  Is 54MHz mandatory when in DAC test mode?

  • The video encoder can run at either 27MHz or 54MHz. 54MHz is prefered since it reduces the requirement for external re-construction filters.

    Changing to 27MHz requires a few changes to the clocks and encoder.

    There are not really any benefits of not using 54MHz and all VENC configurations in Linux etc... all assume 54MHz.

    BR,

    Steve

  • Hi Steve, I'm stirring up this old thread ...

     

    Where does the WritePhysical() function reside?  Is this something for CCS only?  Or does it also get generated when compiling something like DSPLink?  I'd like to access the registers necessary to place the DAC in test mode (and other registers in general) directly from the kernel.  Is this within the capability of DSPLink?  If it is, I'm realizing that the memory mapping becomes important, especially since the DDS is part of the OMAP and OMAP part of the Beagleboard -- I'm hoping the mapping is 1-to-1 for all three (but probably not).  Can you point me to any graphics of the DSS memory map?

     

    thanks.

     

     

  • Here is the source behind the WritePhysical function.

    It performs the physical to logical address mapping. It is for Linux.

    unsigned long ReadPhysical(unsigned long Address)
    {
      int fd;
      void *map_base, *virt_addr;
      unsigned long read_result;

      if((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) FATAL;
      map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, Address & ~MAP_MASK);
      if(map_base == (void *) -1) FATAL;
      virt_addr = map_base + (Address & MAP_MASK);
      read_result = *((unsigned long *) virt_addr);
      if(munmap(map_base, MAP_SIZE) == -1) FATAL;
      close(fd);
      return read_result;
    }

    void WritePhysical(unsigned long Address, unsigned long Data)
    {
      int fd;
      void *map_base, *virt_addr;
      if((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) FATAL;
      map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, Address & ~MAP_MASK);
      if(map_base == (void *) -1) FATAL;
      virt_addr = map_base + (Address & MAP_MASK);
      *((unsigned long *) virt_addr) = Data;
      if(munmap(map_base, MAP_SIZE) == -1) FATAL;
      close(fd);
    }

    BR,

    Steve