dispdrvr.c
来自「PXA255 WINCE 4.2 BSP ,该BSP是商用的。」· C语言 代码 · 共 1,785 行 · 第 1/4 页
C
1,785 行
v_pPWMRegs->pwcr = 0;
// Set the duty cycle to 100% (0x3FF/0x3FF)
v_pPWMRegs->pwdr = 0x3FF;
// Set the period value to it's maximum (0x3FF)
v_pPWMRegs->pwpr = 0x3FF;
}
break;
case LTM04C387S:
{
RETAILMSG(1, (TEXT("Setting display type LTM04C387S")));
PCD = (LCLK / (2 * LTM04C387S_PIXEL_CLOCK_FREQUENCY)) - 1;
v_pLcdRegs->LCCR0 = ( LCD_LDM | LCD_SFM | LCD_IUM | LCD_EFM |
LCD_PAS | LCD_QDM | LCD_BM | LCD_OUM );
v_pLcdRegs->LCCR1 = ( LCD_PPL(0x27F) | LCD_HSW(0x01) |
LCD_ELW(0x01) | LCD_BLW(0x9f) );
v_pLcdRegs->LCCR2 = ( LCD_LPP(0x1df) | LCD_VSW(0x2c) |
LCD_EFW(0x00) | LCD_BFW(0x00) );
v_pLcdRegs->LCCR3 = ( LCD_PCD(PCD) | LCD_BPP(BPP) );
// Setup the Board Control Register (BCR)
// This command turns the display on.
set_BCRVal(LIGHT_ON, NOMASK, gInPowerHandler);
// Set PWM0 to 100% duty cycle to turn on the backlight to full brightness.
// When we wish to change the brightness of the backlight, change the duty cycle.
// Enable graceful shutdown, and prescale count of 1.
v_pPWMRegs->pwcr = 0;
// Set the duty cycle to 100% (0x3FF/0x3FF)
v_pPWMRegs->pwdr = 0x3FF;
// Set the period value to it's maximum (0x3FF)
v_pPWMRegs->pwpr = 0x3FF;
}
break;
case LQ039Q2DS54:
{
RETAILMSG(1, (TEXT("Setting display type LQ039Q2DS54")));
PCD = (LCLK / (2 * LQ039Q2DS54_PIXEL_CLOCK_FREQUENCY)) - 1;
// For now, set PCD = 3;
PCD = 3;
v_pLcdRegs->LCCR0 = ( LCD_LDM | LCD_SFM | LCD_IUM | LCD_EFM |
LCD_PAS | LCD_QDM | LCD_BM | LCD_OUM );
v_pLcdRegs->LCCR1 = ( LCD_PPL(0x13F) | LCD_HSW(0x3e) |
LCD_ELW(0x12) | LCD_BLW(0x39) );
v_pLcdRegs->LCCR2 = ( LCD_LPP(0xef) | LCD_VSW(0x01) |
LCD_EFW(0x00) | LCD_BFW(0x03) );
v_pLcdRegs->LCCR3 = ( LCD_PCD(PCD) | LCD_BPP(BPP) );
// Setup the Board Control Register (BCR)
// Make sure the display is turned on for 300ms before
// turning on the back light.
// This command turns the display on and back light off.
set_BCRVal(LCD_ON, LIGHT_OFF, gInPowerHandler);
msWait(300);
// Now turn the back light on
set_BCRVal(LIGHT_ON, NOMASK, gInPowerHandler);
// Set PWM0 to 100% duty cycle to turn on the backlight to full brightness.
// When we wish to change the brightness of the backlight, change the duty cycle.
// Enable graceful shutdown, and prescale count of 1.
v_pPWMRegs->pwcr = 0;
// Set the duty cycle to 100% (0x3FF/0x3FF)
v_pPWMRegs->pwdr = 0x3FF;
// Set the period value to it's maximum (0x3FF)
v_pPWMRegs->pwpr = 0x3FF;
}
break;
#endif
#ifdef PLAT_LUBBOCK
case LM8V31:
{
PCD = (LCLK / (2 * LM8V31_PIXEL_CLOCK_FREQUENCY)) - 1;
// For now, set PCD = 10;
PCD = 10;
// Reconfigure the upper panel frame descriptors for dual panel operation by
// setting the DMA transfer length to half the size of the frame buffer
frameDescriptorCh0fd1->LDCMD = frameBufferSize >> 1;
frameDescriptorCh0fd2->LDCMD = frameBufferSize >> 1;
// Configure the lower panel frame descriptor for dual panel operation.
// Set the physical address of the frame descriptor
frameDescriptorCh1->FDADR = DMA_CHANNEL_1_FRAME_DESCRIPTOR_BASE_PHYSICAL;
// Set the physical address of the frame buffer
frameDescriptorCh1->FSADR = FRAME_BUFFER_BASE_PHYSICAL+(frameBufferSize>>1);
// Clear the frame ID
frameDescriptorCh1->FIDR = 0;
// Set the DMA transfer length to half the ize of the frame buffer
frameDescriptorCh1->LDCMD = frameBufferSize >> 1;
// Store the physical address of this frame descriptor in the frame descriptor
frameDescriptorCh1->PHYSADDR = frameDescriptorCh1->FDADR;
// FBR1 is cleared and is not used in this implementation
v_pLcdRegs->FBR1 = 0;
// Load the contents of FDADR1 with the physical address of this frame descriptor
v_pLcdRegs->FDADR1 = frameDescriptorCh1->FDADR;
// Configure the TMED dithering engine
// Use the magic number described in the Cotulla EAS, 0x00AA5500;
v_pLcdRegs->TRGBR = LCD_TRS(0x00) | LCD_TGS(0x55) | LCD_TBS(0xAA);
// Use the magic number described in the Cotulla EAS, 0x0000754F;
v_pLcdRegs->TCR = LCD_TM2S | LCD_TM1S | LCD_TM2En | LCD_TM1En |
LCD_TVBS(0x04) | LCD_THBS(0x05) | LCD_TSCS(0x03) |
LCD_TED;
v_pLcdRegs->LCCR1 = ( LCD_PPL(0x27F) | LCD_HSW(0x02) |
LCD_ELW(0x03) | LCD_BLW(0x03) );
v_pLcdRegs->LCCR2 = ( LCD_LPP(0xef) | LCD_VSW(0x01) |
LCD_EFW(0x00) | LCD_BFW(0x00) );
v_pLcdRegs->LCCR3 = ( LCD_PCD(PCD) | LCD_ACB(0xff) |
LCD_PCP | LCD_BPP(BPP) );
v_pLcdRegs->LCCR0 = ( LCD_SDS | LCD_LDM | LCD_SFM | LCD_IUM |
LCD_EFM | LCD_PDD(0x01) | LCD_BM);
}
break;
case LM057QCTT03:
{
PCD = (LCLK / (2 * LM057QCTT03_PIXEL_CLOCK_FREQUENCY)) - 1;
PCD = 23;
// Configure the TMED dithering engine
// Use the magic number described in the Cotulla EAS, 0x00AA5500;
v_pLcdRegs->TRGBR = LCD_TRS(0x00) | LCD_TGS(0x55) | LCD_TBS(0xAA);
// Use the magic number described in the Cotulla EAS, 0x0000754F;
v_pLcdRegs->TCR = LCD_TM2S | LCD_TM1S | LCD_TM2En | LCD_TM1En |
LCD_TVBS(0x04) | LCD_THBS(0x05) | LCD_TSCS(0x03) |
LCD_TED;
v_pLcdRegs->LCCR1 = ( LCD_PPL(0x13F) | LCD_HSW(0x02) |
LCD_ELW(0x03) | LCD_BLW(0x03) );
v_pLcdRegs->LCCR2 = ( LCD_LPP(0xef) | LCD_VSW(0x01) |
LCD_EFW(0x00) | LCD_BFW(0x00) );
v_pLcdRegs->LCCR3 = ( LCD_PCD(PCD) | LCD_ACB(0x10) |
LCD_PCP | LCD_BPP(BPP) );
v_pLcdRegs->LCCR0 = ( LCD_LDM | LCD_SFM | LCD_IUM |
LCD_EFM | LCD_PDD(0x01) | LCD_BM);
}
break;
case TFTQVGA:
{
PCD = (LCLK / (2 * TFTQVGA_PIXEL_CLOCK_FREQUENCY)) - 1;
PCD = 7;
v_pLcdRegs->LCCR1 = ( LCD_PPL(0x13F) | LCD_HSW(0x01) |
LCD_ELW(0x03) | LCD_BLW(0x33) );
v_pLcdRegs->LCCR2 = ( LCD_LPP(0xef) | LCD_VSW(0x02) |
LCD_EFW(0x04) | LCD_BFW(0x04) );
v_pLcdRegs->LCCR3 = ( LCD_PCD(PCD) | LCD_BPP(BPP) |
LCD_PCP | LCD_VSP | LCD_HSP);
v_pLcdRegs->LCCR0 = ( LCD_LDM | LCD_SFM | LCD_IUM |
LCD_EFM | LCD_PAS | LCD_BM);
}
break;
case LQ64D341: // 176x220 Stinger display
{
PCD = (int)(LCLK / (2 * LQ64D341_PIXEL_CLOCK_FREQUENCY)) - 1;
PCD = 12;
v_pLcdRegs->LCCR1 = ( LCD_PPL(0xAF) | LCD_HSW(0x02) |
LCD_ELW(0x7B) | LCD_BLW(0x03) );
v_pLcdRegs->LCCR2 = ( LCD_LPP(0xdb) | LCD_VSW(0x01) |
LCD_EFW(0x02) | LCD_BFW(0x00) );
v_pLcdRegs->LCCR3 = ( LCD_PCD(PCD) | LCD_BPP(BPP) |
LCD_VSP | LCD_HSP | LCD_PCP |
LCD_OEP);
v_pLcdRegs->LCCR0 = ( LCD_LDM | LCD_SFM | LCD_IUM |
LCD_EFM | LCD_PAS | LCD_BM);
}
break;
case LQ64D343: // 640x480
{
v_pLcdRegs->LCCR1 = 0x00a0027f;
v_pLcdRegs->LCCR2 = 0x01207ddf;
v_pLcdRegs->LCCR3 = 0x04700001;
v_pLcdRegs->LCCR0 = 0x003008f8;
}
break;
case SX14Q001: // 320x240
{
v_pLcdRegs->LCCR1 = 0x0202013f;
v_pLcdRegs->LCCR2 = 0x030000ef;
v_pLcdRegs->LCCR3 = 0x03400015;
v_pLcdRegs->LCCR0 = 0x00300a78;
}
break;
#endif
default:
{
RETAILMSG(1, (TEXT("No display type detected!")));
}
break;
}
}
void InitCursor()
{
gDrawCursorFlag = FALSE;
gCursorRect.left = (DispDrvr_cxScreen - CURSOR_XSIZE) >> 1;
gCursorRect.right = gCursorRect.left + CURSOR_XSIZE;
gCursorRect.top = (DispDrvr_cyScreen - CURSOR_YSIZE) >> 1;
gCursorRect.bottom = gCursorRect.top + CURSOR_YSIZE;
gxHot = gyHot = 0;
memset ((BYTE *)gCursorMask, 0xFF, sizeof(gCursorMask));
}
BOOL MapVirtualAddress()
{
v_pLcdRegs = (volatile SA2lcdregs *)VirtualAllocCopy(sizeof(SA2lcdregs),"DispDrvrInitialize : v_pLcdRegs",(PVOID)(LCD_BASE_U_VIRTUAL));
if (!v_pLcdRegs)
{
Cleanup();
return FALSE;
}
v_pClkRegs = (volatile CLKMAN_REGS *)VirtualAllocCopy(sizeof(CLKMAN_REGS),"DispDrvrInitialize : v_pClkRegs",(PVOID)(CLK_BASE_U_VIRTUAL));
if (!v_pClkRegs)
{
Cleanup();
return FALSE;
}
v_pGPIORegs = (volatile GPIO_REGS *)VirtualAllocCopy(sizeof(GPIO_REGS),"DispDrvrInitialize : v_pGPIORegs",(PVOID)(GPIO_BASE_U_VIRTUAL));
if (!v_pGPIORegs)
{
Cleanup();
return FALSE;
}
frameDescriptorCh0fd1 = (volatile LCD_FRAME_DESCRIPTOR *)VirtualAllocCopy(sizeof(LCD_FRAME_DESCRIPTOR), "DispDrvrInitialize : lcdFrameDescriptor", (PVOID)(DMA_CHANNEL_0_FRAME_DESCRIPTOR_BASE_VIRTUAL));
if (!frameDescriptorCh0fd1)
{
Cleanup();
return FALSE;
}
frameDescriptorCh0fd2 = (volatile LCD_FRAME_DESCRIPTOR *)VirtualAllocCopy(sizeof(LCD_FRAME_DESCRIPTOR), "DispDrvrInitialize : lcdFrameDescriptor", (PVOID)(DMA_CHANNEL_0_ALT_FRAME_DESCRIPTOR_BASE_VIRTUAL));
if (!frameDescriptorCh0fd2)
{
Cleanup();
return FALSE;
}
frameDescriptorCh1 = (volatile LCD_FRAME_DESCRIPTOR *)VirtualAllocCopy(sizeof(LCD_FRAME_DESCRIPTOR), "DispDrvrInitialize : lcdFrameDescriptor", (PVOID)(DMA_CHANNEL_1_FRAME_DESCRIPTOR_BASE_VIRTUAL));
if (!frameDescriptorCh1)
{
Cleanup();
return FALSE;
}
frameDescriptorPalette = (volatile LCD_FRAME_DESCRIPTOR *)VirtualAllocCopy(sizeof(LCD_FRAME_DESCRIPTOR), "DispDrvrInitialize : lcdFrameDescriptor", (PVOID)(PALETTE_FRAME_DESCRIPTOR_BASE_VIRTUAL));
if (!frameDescriptorPalette)
{
Cleanup();
return FALSE;
}
v_pPaletteBuffer=(volatile LCD_PALETTE *)VirtualAllocCopy(sizeof(LCD_PALETTE),"DispDrvrInitialize : v_pPaletteBuffer",(PVOID)PALETTE_BUFFER_BASE_VIRTUAL);
if (!v_pPaletteBuffer)
{
Cleanup();
return FALSE;
}
// For Merlin builds, we have the option of using a section mapped address or a page
// mapped address to access the frame buffer. Using a section mapped address has less
// overhead and therefore provides higher performance. We'll configure the bufferable
// attribute for either the section descriptor or the page descriptors as applicable.
#ifdef OSV_LOCAL_MERLIN
// Enter into Kernel mode to enable us to modify the section descriptor
// so that we may set the bufferable bit. This enables write coalescing
// for frame buffer writes when using the section mapped address.
//
// GAPI uses the section mapped address always. We'll configure that section
// descriptor for bufferable operating regardless of the "DISPLAY_DRIVER_USES_SECTION_DESCRIPTOR"
// environment variable.
SetKMode(TRUE);
// Now configure the frame buffer's section descriptor.
// The function GetDescriptorAddress shows how to obtain the correct descriptor address.
// It currently returns a descriptor address of 0xfffd28f4 for the current memory map.
// This descriptor is one of two descriptors that map the the frame buffer.
// The first descriptor found maps the cached virtual address, while the second
// descriptor found maps the uncached virtual address. We want to modify the
// second descriptor, that which maps the uncached virtual address since the uncached virtual
// address is the address we've chosen to use throughout the codebase.
//
// NOTE:
// There's no need to run this dynamically each boot, so it's been left only as an example
// of how to obtain the descriptor address. It could be called as shown below to determine
// the descriptor address dynamically.
// ConfigureFrameBufferSectionDescriptor(GetDescriptorAddress(DMA_CHANNEL_0_FRAME_DESCRIPTOR_BASE_PHYSICAL));
//
// NOTE:
// The section descriptor covers a 1MB section. If the frame buffer ever exceeds 1MB
// in size, you'll need to modify additional section descriptors.
//
ConfigureFrameBufferSectionDescriptor(0xfffd28f4); // Using the descriptor that maps the uncached, virtual address.
#ifdef DISPLAY_DRIVER_USES_SECTION_DESCRIPTOR
// The GDI will use the section mapped address for the frame buffer.
// The bufferable attribute is configured above in the call to ConfigureFrameBufferSectionDescriptor().
gFrameBuffer = (PBYTE)(FRAME_BUFFER_0_BASE_VIRTUAL);
#else // using a page mapped frame buffer for GDI
// The GDI will use a page mapped address for the frame buffer.
// The frame buffer is specifically page mapped via VirtualAllocCopy.
// The bufferable attribute is configured via VirtualSetAttributes.
gFrameBuffer = (PBYTE)VirtualAllocCopy(frameBufferSize*NUM_FRAME_BUFFERS,"gFrameBuffer",(PVOID)(FRAME_BUFFER_0_BASE_VIRTUAL));
if (!gFrameBuffer)
{
Cleanup();
return FALSE;
}
// Set the bufferable bit attribute to the frame buffer to enable write coalescing
// This setting achieves highest performance when drawing to the frame buffer.
VirtualSetAttributes(gFrameBuffer, frameBufferSize*NUM_FRAME_BUFFERS, 4, 4, NULL);
#endif
#else // Not a MERLIN system, so we'll page map the address and won't be setting the bufferable attribute.
// If your version of WinCE.NET supports VirtualSetAttributes(), apply the bufferable setting as above.
// gFrameBuffer = (PBYTE)VirtualAllocCopy(frameBufferSize*NUM_FRAME_BUFFERS,"gFrameBuffer",(PVOID)(FRAME_BUFFER_0_BASE_VIRTUAL));
{
PVOID pVirtAddr;
unsigned offset, size;
pVirtAddr = (PVOID)(FRAME_BUFFER_0_BASE_VIRTUAL);
size = frameBufferSize*NUM_FRAME_BUFFERS;
offset = (unsigned)pVirtAddr & (0x1000 - 1);
size += (offset ? 0x1000 : 0);
pVirtAddr = (PVOID)((unsigned)pVirtAddr - offset);
if (size >= 1024*1024*2)
{
gFrameBuffer = (PBYTE)VirtualAlloc(NULL,size,MEM_RESERVE,PAGE_NOACCESS);
}
else
{
gFrameBuffer = (PBYTE)VirtualAlloc(NULL,1024*1024*2,MEM_RESERVE,PAGE_NOACCESS);
}
if (!VirtualCopy(gFrameBuffer,pVirtAddr,size,PAGE_READWRITE|PAGE_NOCACHE))
{
gFrameBuffer = NULL;
}
else
{
gFrameBuffer += offset;
}
}
if (!gFrameBuffer)
{
Cleanup();
return FALSE;
}
// Set the bufferable bit attribute to the frame buffer to enable write coalescing
// This setting achieves highest performance when drawing to the frame buffer.
VirtualSetAttributes(gFrameBuffer, frameBufferSize*NUM_FRAME_BUFFERS, 4, 4, NULL);
#endif
gBlankFrameBuffer = (PBYTE) VirtualAlloc(0, frameBufferSize, MEM_RESERVE | MEM_COMMIT,PAGE_READWRITE);
if (!gBlankFrameBuffer)
{
Cleanup();
return FALSE;
}
#ifdef PLAT_LUBBOCK
v_pBoardLevelRegister=(volatile BLR_REGS *)VirtualAllocCopy(sizeof(BLR_REGS),"DispDrvrInitialize : v_pPaletteBuffer",(PVOID)FPGA_REGS_BASE_U_VIRTUAL);
if (!v_pBoardLevelRegister)
{
Cleanup();
return FALSE;
}
#endif
#ifdef PLAT_SANDGATE
v_pPWMRegs=(volatile PWM_REGS *)VirtualAllocCopy(sizeof(PWM_REGS),"DispDrvrInitialize : v_pPaletteBuffer",(PVOID)PWM0_BASE_U_VIRTUAL);
if (!v_pPWMRegs)
{
Cleanup();
return FALSE;
}
#endif
return TRUE;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?