⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vid_1200.c

📁 WinCE 3.0 BSP, 包含Inter SA1110, Intel_815E, Advantech_PCM9574 等
💻 C
📖 第 1 页 / 共 3 页
字号:
/*-----------------------------------------------------------------------------
 * VID_1200.C
 *
 * Version 2.0 - February 21, 2000
 *
 * This file contains routines to control the SC1200 video overlay hardware.
 *
 * History:
 *    Versions 0.1 through 2.0 by Brian Falardeau.
 *
 * Copyright (c) 1999-2000 National Semiconductor.
 *-----------------------------------------------------------------------------
 */

/* GLOBAL VARIABLES */
/* Needed to save intended color key values since the color key */
/* registers are required to truly disable the video window. */

unsigned long sc1200_color_key = 0;
unsigned long sc1200_color_mask = 0;
int sc1200_alpha_enable[3];

/*----------------------------------------------------------------------------
 * SC1200 PLL TABLE
 *----------------------------------------------------------------------------
 */

typedef struct tagSC1200PLL
{
    long frequency;                 /* 16.16 fixed point frequency */
    unsigned long clock_select;     /* clock select register (0x2C) */
} SC1200PLL;

SC1200PLL gfx_sc1200_clock_table[] = {                                 
    { 0x00192CCC, 0x00000000 }, /*  25.1750 */
    { 0x001F8000, 0x00010000 }, /*  31.5000 */
    { 0x00240000, 0x00020000 }, /*  36.0000 */
    { 0x00280000, 0x00030000 }, /*  40.0000 */
    { 0x00318000, 0x00050000 }, /*  49.5000 */
    { 0x00320000, 0x00040000 }, /*  50.0000 */
    { 0x00384000, 0x00060000 }, /*  56.2500 */
    { 0x00410000, 0x00080000 }, /*  65.0000 */
    { 0x004E8000, 0x000A0000 }, /*  78.5000 */
    { 0x005E8000, 0x000B0000 }, /*  94.5000 */
    { 0x006C0000, 0x000C0000 }, /* 108.0000 */
    { 0x00870000, 0x000D0000 }, /* 135.0000 */
};

#define NUM_SC1200_FREQUENCIES sizeof(gfx_sc1200_clock_table)/sizeof(SC1200PLL)

/*---------------------------------------------------------------------------
 * gfx_reset_video (PRIVATE ROUTINE: NOT PART OF DURANGO API)
 *
 * This routine is used to disable all components of video overlay before
 * performing a mode switch.
 *---------------------------------------------------------------------------
 */
#if GFX_VIDEO_DYNAMIC
void sc1200_reset_video(void)
#else
void gfx_reset_video(void)
#endif
{
    gfx_set_video_enable(0);
    gfx_select_alpha_region(0);
    gfx_set_alpha_enable(0);
    gfx_select_alpha_region(1);
    gfx_set_alpha_enable(0);
    gfx_select_alpha_region(2);
    gfx_set_alpha_enable(0);
}

/*---------------------------------------------------------------------------
 * gfx_set_clock_frequency
 *
 * This routine sets the clock frequency, specified as a 16.16 fixed point
 * value (0x00318000 = 49.5 MHz).  It will set the closest frequency found
 * in the lookup table.
 *---------------------------------------------------------------------------
 */
#if GFX_VIDEO_DYNAMIC
void sc1200_set_clock_frequency(unsigned long frequency)
#else
void gfx_set_clock_frequency(unsigned long frequency)
#endif
{
    int index;
    unsigned long value;
    long min, diff;

    /* FIND THE REGISTER VALUES FOR THE DESIRED FREQUENCY */
    /* Search the table for the closest frequency (16.16 format). */

    value = gfx_sc1200_clock_table[0].clock_select;
    min = (long) gfx_sc1200_clock_table[0].frequency - frequency;
    if (min < 0L) min = -min;
    for (index = 1; index < NUM_SC1200_FREQUENCIES; index++)
    {
        diff = (long) gfx_sc1200_clock_table[index].frequency - frequency;
        if (diff < 0L) diff = -diff;
        if (diff < min)
        {
            min = diff; 
            value = gfx_sc1200_clock_table[index].clock_select;
        }
    }

    /* SET THE DOT CLOCK REGISTER */

    WRITE_VID32(SC1200_VID_MISC, 0x00001000);
    WRITE_VID32(SC1200_VID_CLOCK_SELECT, value);
    return;
}

/*-----------------------------------------------------------------------------
 * gfx_set_video_enable
 *
 * This routine enables or disables the video overlay functionality.
 *-----------------------------------------------------------------------------
 */
#if GFX_VIDEO_DYNAMIC
int sc1200_set_video_enable(int enable)
#else
int gfx_set_video_enable(int enable)
#endif
{
    int i;
    unsigned long alpha, vcfg;

    /* WAIT FOR VERTICAL BLANK TO START */
    /* Otherwise a glitch can be observed. */

    if (gfx_test_timing_active())
    {
        if (!gfx_test_vertical_active())
        {
            while(!gfx_test_vertical_active());
        }
        while(gfx_test_vertical_active());
    }
    vcfg = READ_VID32(SC1200_VIDEO_CONFIG);
    if (enable)
    {
        /* ENABLE VIDEO OVERLAY FROM DISPLAY CONTROLLER */
        /* Use private routine to abstract the display controller. */

        gfx_set_display_video_enable(1);
        
        /* SET SC1200 BUS CONTROL PARAMETERS */
        /* Currently always high speed, 8-bit interface. */

        vcfg |= SC1200_VCFG_HIGH_SPD_INT;
        vcfg &= ~(SC1200_VCFG_EARLY_VID_RDY | SC1400_VCFG_16_BIT_EN);

        /* ENABLE SC1200 VIDEO OVERLAY */

        vcfg |= SC1200_VCFG_VID_EN;
        WRITE_VID32(SC1200_VIDEO_CONFIG, vcfg);

        /* RESTORE SC1200 COLOR KEY VALUE */

        WRITE_VID32(SC1200_VIDEO_COLOR_KEY, sc1200_color_key);
        WRITE_VID32(SC1200_VIDEO_COLOR_MASK, sc1200_color_mask);

        /* RESTORE ALPHA ENABLE FOR ALL 3 REGIONS */

        for (i = 0; i < 3; i++)
        {
            if (sc1200_alpha_enable[i])
            {
                alpha = READ_VID32(SC1200_ALPHA_CONTROL_1 + (i << 4));
                alpha |= (1L << 16);
                WRITE_VID32(SC1200_ALPHA_CONTROL_1 + (i << 4), alpha);
            }
        }
    }
    else
    {
        /* DISABLE VIDEO OVERLAY FROM DISPLAY CONTROLLER */
        /* Use private routine to abstract the display controller. */

        gfx_set_display_video_enable(0);
        
        /* DISABLE SC1200 VIDEO OVERLAY */
        /* Really only blanks video - hence use of color key. */

        vcfg &= ~SC1200_VCFG_VID_EN;
        WRITE_VID32(SC1200_VIDEO_CONFIG, vcfg);

        /* USE COLOR KEY VALUE TO REALLY DISABLE WINDOW */
        /* Key and mask set to 0xFFFFFF will disable window */

        WRITE_VID32(SC1200_VIDEO_COLOR_KEY, 0xFFFFFF);
        WRITE_VID32(SC1200_VIDEO_COLOR_MASK, 0xFFFFFF);

        /* DISABLE ALL 3 ALPHA REGIONS */

        for (i = 0; i < 3; i++)
        {
            alpha = READ_VID32(SC1200_ALPHA_CONTROL_1 + (i << 4));
            alpha &= ~(1 << 16);
            WRITE_VID32(SC1200_ALPHA_CONTROL_1 + (i << 4), alpha);
        }
    }
    return(0);
}

/*-----------------------------------------------------------------------------
 * gfx_set_video_format
 *
 * Currently only sets 4:2:2 format, Y1 V Y0 U.
 *-----------------------------------------------------------------------------
 */
#if GFX_VIDEO_DYNAMIC
int sc1200_set_video_format(unsigned long format)
#else
int gfx_set_video_format(unsigned long format)
#endif
{
    unsigned long ctrl, vcfg = 0;

    /* SET THE SC1200 VIDEO INPUT FORMAT */

    vcfg = READ_VID32(SC1200_VIDEO_CONFIG);
    vcfg &= ~(SC1200_VCFG_VID_INP_FORMAT | SC1200_VCFG_4_2_0_MODE);
    vcfg &= ~(SC1200_VCFG_CSC_BYPASS);
    if (format < 4) vcfg |= (format << 2);
    WRITE_VID32(SC1200_VIDEO_CONFIG, vcfg);

    /* SET THE VIDEO COLOR SPACE CONVERSION BIT */
    /* ### Currently always set for 4:2:2 YUV */

    ctrl = READ_VID32(SC1200_VID_ALPHA_CONTROL);
    ctrl |= (1 << 10); /* set bit 10 */
    WRITE_VID32(SC1200_VID_ALPHA_CONTROL, ctrl);
    return(0);
}

/*-----------------------------------------------------------------------------
 * gfx_set_video_size
 *
 * This routine specifies the size of the source data.  It is used only 
 * to determine how much data to transfer per frame, and is not used to 
 * calculate the scaling value (that is handled by a separate routine).
 *-----------------------------------------------------------------------------
 */
#if GFX_VIDEO_DYNAMIC
int sc1200_set_video_size(unsigned short width, unsigned short height)
#else
int gfx_set_video_size(unsigned short width, unsigned short height)
#endif
{
    unsigned long size, vcfg;

    /* SET THE SC1200 VIDEO LINE SIZE */

    vcfg = READ_VID32(SC1200_VIDEO_CONFIG);
    vcfg &= ~(SC1200_VCFG_LINE_SIZE_LOWER_MASK | SC1200_VCFG_LINE_SIZE_UPPER);
    size = (width >> 1);
    vcfg |= (size & 0x00FF) << 8;
    if (size & 0x0100) vcfg |= SC1200_VCFG_LINE_SIZE_UPPER;
    WRITE_VID32(SC1200_VIDEO_CONFIG, vcfg);

    /* SET TOTAL VIDEO BUFFER SIZE IN DISPLAY CONTROLLER */
    /* Use private routine to abstract the display controller. */

    gfx_set_display_video_size(width, height);
    return(0);
}

/*-----------------------------------------------------------------------------
 * gfx_set_video_offset
 *
 * This routine sets the starting offset for the video buffer when only 
 * one offset needs to be specified.
 *-----------------------------------------------------------------------------
 */
#if GFX_VIDEO_DYNAMIC
int sc1200_set_video_offset(unsigned long offset)
#else
int gfx_set_video_offset(unsigned long offset)
#endif
{
    /* SAVE VALUE FOR FUTURE CLIPPING OF THE TOP OF THE VIDEO WINDOW */

    gfx_vid_offset = offset;

    /* SET VIDEO BUFFER OFFSET IN DISPLAY CONTROLLER */
    /* Use private routine to abstract the display controller. */

    gfx_set_display_video_offset(offset);
    return(0);
}

/*---------------------------------------------------------------------------
 * gfx_set_video_scale
 * 
 * This routine sets the scale factor for the video overlay window.  The 
 * size of the source and destination regions are specified in pixels.  
 *---------------------------------------------------------------------------
 */
#if GFX_VIDEO_DYNAMIC
int sc1200_set_video_scale(unsigned short srcw, unsigned short srch, 
    unsigned short dstw, unsigned short dsth)
#else
int gfx_set_video_scale(unsigned short srcw, unsigned short srch, 
    unsigned short dstw, unsigned short dsth)
#endif
{
    unsigned long xscale, yscale;

    /* SAVE PARAMETERS */
    /* These are needed for clipping the video window later. */

    gfx_vid_srcw = srcw;
    gfx_vid_srch = srch;
    gfx_vid_dstw = dstw;
    gfx_vid_dsth = dsth;

    /* CALCULATE SC1200 SCALE FACTORS */
    /* No downscaling in SC1200 so force to 1x if attempted. */

    if (srcw < dstw) xscale = (0x2000 * (srcw - 1)) / (dstw - 1);
    else xscale = 0x1FFF;
    if (srch < dsth) yscale = (0x2000 * (srch - 1)) / (dsth - 1);
    else yscale = 0x1FFF;
    WRITE_VID32(SC1200_VIDEO_SCALE, (yscale << 16) | xscale);

    /* CALL ROUTINE TO UPDATE WINDOW POSITION */
    /* This is required because the scale values effect the number of */
    /* source data pixels that need to be clipped, as well as the */
    /* amount of data that needs to be transferred. */

    gfx_set_video_window(gfx_vid_xpos, gfx_vid_ypos, gfx_vid_width,
        gfx_vid_height);
    return(0);
}


/*---------------------------------------------------------------------------
 * gfx_set_video_window
 * 
 * This routine sets the position and size of the video overlay window.  The 
 * position is specified in screen relative coordinates, and may be negative.  
 * The size of destination region is specified in pixels.  The line size
 * indicates the number of bytes of source data per scanline.
 *---------------------------------------------------------------------------
 */
#if GFX_VIDEO_DYNAMIC
int sc1200_set_video_window(short x, short y, unsigned short w, 
    unsigned short h)
#else
int gfx_set_video_window(short x, short y, unsigned short w, 
    unsigned short h)
#endif
{
    unsigned long vcfg = 0;
    unsigned long hadjust, vadjust;
    unsigned long initread;
    unsigned long xstart, ystart, xend, yend;
    unsigned long offset, line_size;

    /* SAVE PARAMETERS */
    /* These are needed to call this routine if the scale value changes. */

    gfx_vid_xpos = x;
    gfx_vid_ypos = y;
    gfx_vid_width = w;
    gfx_vid_height = h;

    /* GET ADJUSTMENT VALUES */
    /* Use routines to abstract version of display controller. */

    hadjust = gfx_get_htotal() - gfx_get_hsync_end() - 13;
    vadjust = gfx_get_vtotal() - gfx_get_vsync_end() + 1;

    if (x > 0) 
    {
        /* NO CLIPPING ON LEFT */

        xstart = x + hadjust;
        initread = 0;
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -