clcd.c
来自「ARM9基于WINDOWSCE的BSP源代码」· C语言 代码 · 共 643 行 · 第 1/2 页
C
643 行
* 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)
{
ULONG Cntrl_BPP;
Cntrl = READ_REGISTER_ULONG(v_pDisplayRegs + LCD_CONTROL_OFFSET);
switch(DispDrvr_cdwStride * 32 / 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 ;
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);
}
/******************************************************************************\
* 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 + =
减小字号Ctrl + -
显示快捷键?