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

📄 clcd.c

📁 此压缩包为杰得开发得z228的BSP的源代码,可以实现很多功能,尤其是视频解码有很好的效果.
💻 C
📖 第 1 页 / 共 2 页
字号:
static void DispPowerOn(BOOL bInPowerHandler);
static void DispPowerOff(BOOL bInPowerHandler);

// Convert 24bit RGB into 16bit value to fit into CLCD palette register
#ifndef CLCD_565    // in original 1555 mode

//I|BBBBB|GGGGG|RRRRR
//(1)  >>3   red lsb
//(2)  >>3 then <<5 so <<2 
//(3)  >>3 then <<10 so <<7  
#define PALCONV(_v_) (((((UINT32)(_v_).peRed  ) >> 3) & 0x001f) | \
                      ((((UINT32)(_v_).peGreen) << 2) & 0x03e0) | \
                      ((((UINT32)(_v_).peBlue ) << 7) & 0x7c00))

#else                   // new 565 true 16 bit mapping

//RRRRR|GGGGGG|BBBBB
//(1) >>3 then <<11 so <<8
//(2) >>2 then <<5  so <<3
//(3) >>3 
#define PALCONV(_v_) (((((UINT32)(_v_).peRed  ) << 8) & 0xF800) | \
                      ((((UINT32)(_v_).peGreen) << 3) & 0x07e0) | \
                      ((((UINT32)(_v_).peBlue ) >> 3) & 0x001f))

#endif

/******************************************************************************\
* Description:  Find the required ratio of the Panel Clock to the CLCD clock.  *
* Operation:    The Panel Clock is generated by a divisor applied to the CLCD  *
*               Clock. This function uses values from the parameter structure  *
*               to generate a divisor that gives a refresh rate close to that  *
*               requested.                                                     *
*               This is done by calculating the effective clocked area of the  *
*               LCD, and using the requested refresh rate to find the Panel    *
*               Clock frequency that gives the desired refresh rate. From this *
*               the required divisor is derived.                               *
*               The ratio is often a small integer so the refresh rate set up  *
*               can be (considerably) different from that requested. Because   *
*               of this the actual refresh rate expected is computed and saved *
*               in the parameter structure.                                    *
* NOTE:  The LCD display is clocked across its active area and additional      *
*        regions around its edge. These extra regions are the Horizontal Front *
*        and Back Porches, the Vertical Front and Back Porches, the Horizontal *
*        and vertical synch regions. This affects the total number of clock    *
*        ticks needed to process a single frame.                               *
*        Since each LCD pixel is made up of a number of discrete elements,     *
*        another factor determines the number of elements clocked by each tick *
*        so there may be a non-integral number of clock ticks per pixel.       *
*        This value varies between different panel types.                      *
\******************************************************************************/
/*
int CLCD_ClockRatioCompute(void)
{
    ULONG PixPerFrame;
    ULONG PanelClockFrequency;
    int Ratio;                           // This could be negative
        // For TFT displays, PCD can go down to 0, ie the ratio is 2. However,
        // if the ratio is less than 2, the pixel clock divisor is bypassed,
        // and so that this case can be detected the minimum value is 1
    int MinRatio = 1;            // This gives PCD = 0, the minimum for TFT

    // Calculate raw number of clocks per frame

    // Firstly find the total number of pixels over to whole display, both
    // active and inactive. This is the total clocked width (Nominal width +
    // Horizontal Front + Back Porche) multiplied by the total clocked height
    // (Nominal height + Vertical Front and Back Porches)
    PixPerFrame = ( ( DISPDRVR_CXSCREEN + HSYNC_VALUE
                      + HFRONT_VALUE + HBACK_VALUE )
                    *
                    ( DispDrvr_cyScreen + VSYNC_VALUE
                      + VFRONT_VALUE + VBACK_VALUE ));
       // Deduce the nominal required Clock frequency for the refresh rate
    PanelClockFrequency = PixPerFrame * FRAME_RATE;

    Ratio = (LCD_CLOCK / PanelClockFrequency);

    if(Ratio < MinRatio)          // Ensure value used is sensible
    {
        Ratio = MinRatio;
    }
    return Ratio;
}
*/
/******************************************************************************\
* Description:  CLCD Timing0 register setup                                    *
* Operation:    Generates the appropriate pattern for the Timing0 register     *
*               from the current parameters defined and loads the register     *
\******************************************************************************/

void CLCD_Timing0Set(void)
{
    ULONG reg = 0;

    apBIT_SET(reg, CLCD_TIMING0_PPL, DispDrvr_cxScreen / 16 - 1); //14
    apBIT_SET(reg, CLCD_TIMING0_HSW, HSYNC_VALUE - 1);
    apBIT_SET(reg, CLCD_TIMING0_HFP, HFRONT_VALUE -1);
    apBIT_SET(reg, CLCD_TIMING0_HBP, HBACK_VALUE - 1);
 
    WRITE_REGISTER_ULONG(v_pDisplayRegs + LCD_TIMING0_OFFSET, TIM0_VALUE);
}

/******************************************************************************\
* Description:  Timing1 register setup                                         *
* Operation:    Generates the appropriate pattern for the Timing1 register     *
*               from the current parameters defined and loads the register     *
\******************************************************************************/
void CLCD_Timing1Set(void)
{
    ULONG reg = 0;
    
    apBIT_SET(reg, CLCD_TIMING1_LPP, DispDrvr_cyScreen - 1);
    if(VSYNC_VALUE)             
    {
        apBIT_SET(reg, CLCD_TIMING1_VSW, VSYNC_VALUE - 1);
    }
    else
    {
        apBIT_SET(reg, CLCD_TIMING1_VSW, VSYNC_VALUE);
    }
    apBIT_SET(reg, CLCD_TIMING1_VFP, VFRONT_VALUE);
    apBIT_SET(reg, CLCD_TIMING1_VBP, VBACK_VALUE);
    WRITE_REGISTER_ULONG(v_pDisplayRegs + LCD_TIMING1_OFFSET, TIM1_VALUE);
}

/******************************************************************************\
* Description:  Timing2 register setup                                         *
* Operation:    Uses the current parameters to generate the Timing2 register   *
*               and loads the register                                         *
\******************************************************************************/
void CLCD_Timing2Set(void)
{
    ULONG reg = 0;              
    //int PCD; 

   /* PCD = CLCD_ClockRatioCompute();
    if(PCD < 2)                 // This can only happen if its TFT
    {
        reg |= CLCD_TIMING2_MASK_BCD;  // Bypass Clock divisor instead of PCD
    }
    else
    {
        apBIT_SET(reg, CLCD_TIMING2_PCD, PCD - 2);
    }*/
    /*BCD=0 to NOT bypass the clcd clock*/
    //reg |= CLCD_TIMING2_MASK_BCD;
    apBIT_SET(reg, CLCD_TIMING2_CPL, DispDrvr_cxScreen-1);
    apBIT_SET(reg, CLCD_TIMING2_ACB, ACBIAS);
    reg |= (  (ULONG)((ULONG) VSYNCACTIVE << bsCLCD_TIMING2_IVS)
            | (ULONG)((ULONG) HSYNCACTIVE << bsCLCD_TIMING2_IHS)
            | (ULONG)((ULONG) DATADRIVE   << bsCLCD_TIMING2_IPC)
            | (ULONG)((ULONG) CLOCKSOURCE << bsCLCD_TIMING2_CLKSEL)
            | (ULONG)((ULONG) TFTCLAC     << bsCLCD_TIMING2_IEO)
            | (ULONG)((ULONG) PCD_VALUE   << bsCLCD_TIMING2_PCD)
           );

    WRITE_REGISTER_ULONG(v_pDisplayRegs + LCD_TIMING2_OFFSET,TIM2_VALUE);

}

/******************************************************************************\
* Description:  Timing3 register setup                                         *
* Operation:    Generates the appropriate pattern for the Timing3 register     *
*               from the current parameters and loads the register             *
\******************************************************************************/
void CLCD_Timing3Set(void)
{
    ULONG reg = CLLEDELAY;

    if (reg != 0)
    {
        reg -= 1;
        reg |= CLCD_TIMING3_MASK_LEE;
    }
    WRITE_REGISTER_ULONG(v_pDisplayRegs + LCD_TIMING3_OFFSET, reg);
}

/******************************************************************************\
* Description:  Set up CLCD palette registers                                  *
* Operation:    Convert the palatte value from 24bit into 16bits so it can be  *
*               fit into 32x128 palatte registers in CLCD                      *
\******************************************************************************/
void DispDrvrSetupPalette(void)
{
    UINT i;

    /*
    ** Table has 24-bit RGB, and 256 entries
    ** CLCD palette is 16-bit, with 2 values in each of 128 entries.
    */
    ASSERT(PALETTE_SIZE==256);
    for (i = 0; i < 128; i++)
        WRITE_REGISTER_ULONG(v_pDisplayRegs + LCD_PALETTE_OFFSET + i*4, 
                 PALCONV(_rgbIdentity[2*i]) |
                 (PALCONV(_rgbIdentity[2*i+1]) << 16)) ;
}

/******************************************************************************\
* Description:  Initialize CLCD registers                                      *
* Operation:    Set up virtual memory to access CLCD registers                 *
*               Call CLCD Powerup rountine to set up registers                 *
\******************************************************************************/
void DispDrvrInitialize (void)
{
    PHYSICAL_ADDRESS PhysicalAddress;
    
    DEBUGMSG( TRUE, (TEXT("MODULE NAME: %s\r\n"),part_name) );
    DEBUGMSG( TRUE, (TEXT("MODULE VERSION: %s\r\n"),part_num) );
    
//  RETAILMSG (1,(TEXT("Initializing ARM Color LCD\r\n")));   

    PhysicalAddress.HighPart = 0;
    PhysicalAddress.LowPart = PHYS_CLCD_CNTL_BASE;
    v_pDisplayRegs = (P_BYTE) MmMapIoSpace (PhysicalAddress, 
                                            SIZE_CLCD_CNTL_REGS, FALSE);
    if(v_pDisplayRegs == NULL)
    {
      ERRORMSG(1,(TEXT("DispDrvrInit: MmMapIoSpace of v_pDisplayRegs failed! (1)\r\n")));
      goto error_return;
    }


    // Make sure that power is off.
    Cntrl = READ_REGISTER_ULONG(v_pDisplayRegs + LCD_CONTROL_OFFSET);
    if ((Cntrl & LCD_CONTROL_PWR) || (Cntrl & LCD_CONTROL_ENABLE))
    {
      // Turn the power off
      DispPowerOff(FALSE);
    }
    
    // Power up the LCD
    DispPowerOn(FALSE); 

    return;

    
error_return:

    if(  (v_pDisplayRegs ))   
    {
        MmUnmapIoSpace( (void *) v_pDisplayRegs, SIZE_CLCD_CNTL_REGS );
    }
    if( v_pSYS_CTRLRegisters )
    {
        MmUnmapIoSpace( (void *) v_pSYS_CTRLRegisters, SIZE_SYS_CNTL_REGS );
    }

    return;
}


/******************************************************************************\
* Description:  Routine to power on/off the display hardware.                  *
* Note:         This function is usually called in kernel context, and should  *
*               not make any system calls. So, implement delays as spin loops  *
*               instead of using Sleep().                                      *
\******************************************************************************/
void DispDrvrPowerHandler(BOOL  bOff)
{
    if(bOff) 
        DispPowerOff(TRUE);
    else
        DispPowerOn(TRUE);
}

/******************************************************************************\
* Description:  CLCD power on routine                                          *
* Operation:    This function configures CLCD registers to a working state     *
\******************************************************************************/
static void DispPowerOn(BOOL bInPowerHandler)
{
#if 1	
    ULONG   Cntrl_BPP;
    Cntrl = READ_REGISTER_ULONG(v_pDisplayRegs + LCD_CONTROL_OFFSET);

    switch(DispDrvr_cdwStride * 24 / DispDrvr_cxScreen)
    {
        case 8:
            Cntrl_BPP = LCD_CONTROL_8BPP;
            /* when power on, also initiate the palette table registers */
            DispDrvrSetupPalette();
            break;
        case 16:
            Cntrl_BPP = LCD_CONTROL_16BPP;
            break;
        case 24:
            Cntrl_BPP = LCD_CONTROL_24BPP;
            break;
        default:
            Cntrl_BPP = LCD_CONTROL_16BPP;
            break;
    }

    //water mark level 16
    Cntrl = 0x00030000|
            LCD_CONTROL_VCOMP_BACKP |
            LCD_CONTROL_TFT |
            Cntrl_BPP |
            LCD_CONTROL_BEPO ;

    WRITE_REGISTER_ULONG(v_pDisplayRegs + LCD_CONTROL_OFFSET,Cntrl);

    // Setup the timing registers
    CLCD_Timing0Set();
    CLCD_Timing1Set();
    CLCD_Timing2Set();
    CLCD_Timing3Set();

    // Setup the Frame buffer address
    WRITE_REGISTER_ULONG(v_pDisplayRegs + LCD_FRAMBUF_OFFSET,
                          CLCD_FRAME_BUFFER);



    Cntrl = LCD_CONTROL_VCOMP_BACKP |
            LCD_CONTROL_TFT |
            Cntrl_BPP   |
            LCD_CONTROL_ENABLE |
            LCD_CONTROL_BEPO |
			LCD_CONTROL_BGR;

    WRITE_REGISTER_ULONG(v_pDisplayRegs + LCD_CONTROL_OFFSET,Cntrl);

    // TRM indicates that some displays must have a delay between power on/off
    // and enabling/disabling the LCD peripheral.
    // If your display requires such a delay it should be inserted here.

    Cntrl |= LCD_CONTROL_PWR;

    WRITE_REGISTER_ULONG(v_pDisplayRegs + LCD_CONTROL_OFFSET,Cntrl);
    RETAILMSG( 1,(TEXT("CLCD DispPowerOn\r\n")));
              
#endif

#if 0
    WRITE_REGISTER_ULONG(v_pDisplayRegs + LCD_CONTROL_OFFSET, LCD_LCDCTRL_CLOSE_VALUE);

    // Setup the timing registers
    CLCD_Timing0Set();
    CLCD_Timing1Set();
    CLCD_Timing2Set();
    CLCD_Timing3Set();

    // Setup the Frame buffer address
    WRITE_REGISTER_ULONG(v_pDisplayRegs + LCD_FRAMBUF_OFFSET,
                          CLCD_FRAME_BUFFER);

    WRITE_REGISTER_ULONG(v_pDisplayRegs + LCD_CONTROL_OFFSET, LCD_LCDCTRL_OPEN_VALUE);
    RETAILMSG( 1,(TEXT("DispPowerOn new\r\n")));
#endif

}


/******************************************************************************\
* Description:  CLCD power off routine                                         *
* Operation:    This function configures registers to turn off the CLCD        *
\******************************************************************************/
static void DispPowerOff(BOOL bInPowerHandler)
{
    Cntrl &= ~LCD_CONTROL_PWR;
    WRITE_REGISTER_ULONG(v_pDisplayRegs + LCD_CONTROL_OFFSET, Cntrl);

    // TRM indicates that some displays must have a delay between power on/off
    // and enabling/disabling the LCD peripheral.
    // If your display requires such a delay it should be inserted here.

    Cntrl &= ~LCD_CONTROL_ENABLE;

    WRITE_REGISTER_ULONG(v_pDisplayRegs + LCD_CONTROL_OFFSET, Cntrl);

}

⌨️ 快捷键说明

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