📄 amadisp.cpp
字号:
//
// Copyright (c) 1997 Microsoft Corporation.
// Copyright (c) 1998-2003 Renesas Technology Corp.
// All Rights Reserved.
//
// HD64404 Standard Display Driver
//
//
// FILE : AMADISP.CPP
// CREATED : 1997.--.-- ("wrap2bpp.cpp" in Windows CE 2.10 environment)
// MODIFIED : 2003. 6.17
// AUTHOR : Renesas Technology Corp.
// HARDWARE : US7751-HRPxxC (BigSur with HD64404, ITS-DS2A)
// HS7751RSTC01H (S1-E, ITS-DS5)
// TARGET OS : Microsoft(R) Windows(R) CE .NET 4.2
// FUNCTIONS : Main part of GPE display driver
// HISTORY : (history not certain)
// 1998.11.--
// - Q2Disp.cpp (for HD64413) is created by modifying
// "wrap2bpp.cpp" in the WinCE2.10 developping environment.
// (some modification is applied in 1999 and 2000.)
// 2001. 7.23
// - Modified for HD64404.
// 2001. 8.24
// - Modified to use linear-to-tile address translation and
// assigned FG frame buffer for GPE screen buffer.
// 2001. 8.30
// - Mouse pointer support is added.
// 2001.10.11
// - Hardware initializations in "dispdrvr.c" are moved to this
// code. File "dispdrvr.c" is removed.
// 2001.10.30
// - File "config.cpp" is added to support configuration with
// parameters from registry.
// - GPEEnableDriver and DrvEnableDriver that are defined in
// "config.cpp" are removed from this file.
// 2002. 1.28
// - g_dwLocalMemoryAddress is added to keep top address of
// HD64404 locally-connected SDRAM.
// - g_dwVideoMemoryAddress is renamed to g_dwVideoMemoryOffset.
// 2002. 2. 7
// - Include file "amanda.h" is renamed to "hd64404.h".
// 2002. 3. 4
// - Cursor color problem on 16bpp is fixed.
// 2002. 6.12
// - Driver version string is moved to "version.h".
// - Frame buffer clean-up is added in SetMode.
// 2002. 8.01
// - Some unused local variables are removed.
// 2002. 9.25
// - Message outputs are removed from power handler.
// - Header style and message text are changed.
// 2002.11.27
// - SetClock is added to support ICD2053B Programmable Clock
// Generator.
// - Register base globals for each modules are removed and
// g_dwRegisterAddress that is the register base global for all
// HD64404 modules is added.
// 2003. 6.17
// - GPIO clock control in SetClock is modified to turn on only
// while programming ICD2053B.
// - Header file that keeps driver version string is renamed from
// "VERSION.H" to "VER_AMADISP_STD.H".
// - For power management operation, API calls are removed from
// PowerHandler.
//----------------------------------------------------------------------------
#define DDI 1
#include <windows.h>
#include <types.h>
#include <winddi.h>
#include <gpe.h>
#include "amadisp.h"
#include "hd64404.h"
#include "dispregs.h"
#include "palette.h"
#include "drvlib.h"
#include "ver_amadisp_std.h"
DWORD gxHot;
DWORD gyHot;
#define NUMDISPMODES 1
ModeInit AMADispMode[NUMDISPMODES];
INSTANTIATE_PALETTE
INSTANTIATE_GPE_ZONES(0x3,"GDI Driver","unused1","unused2") /* Start with Errors and warnings */
// Global variables to pass driver configurations, initialized in DrvEnableDriver.
DWORD g_dwLocalMemoryAddress;
DWORD g_dwVideoMemoryOffset;
DWORD g_dwVideoMemorySize;
DWORD g_dwRegisterAddress;
DWORD g_dwFrameBufferSize;
DWORD g_dwFrameBufferOffset;
DWORD g_dwDisplayClock;
DWORD g_dwWorkAreaOffset;
DWORD g_dwWorkAreaSize;
DWORD g_dwSystemDLAreaOffset;
DWORD g_dwSystemDLAreaSize;
DWORD g_dwCursorAreaSize;
DWORD g_dwCursorAreaOffset;
DWORD g_dwCursorBlinkFrames;
TCHAR* g_szModeString;
// AdjustMicroSecondsToLoopCount is not applicable in power handler.
// This variable is used to keep multiplier to calculate BusyWait loop count
// from required milliseconds to wait.
DWORD g_dwLoop1ms;
static GPE *pGPE = (GPE *)NULL;
// Main entry point for a GPE-compliant driver
GPE *GetGPE()
{
DEBUGMSG(GPE_ZONE_ENTER,(TEXT("GetGPE\r\n")));
if (!pGPE)
pGPE = new AMADisp();
return pGPE;
}
AMADisp::AMADisp()
{
DEBUGMSG(GPE_ZONE_ENTER, (TEXT("AMADisp::AMADisp\r\n")));
// variables for displaying clock frequency
int nFreqMhz = (int)(g_dwDisplayClock / 1000000);
int nFactor1 = nFreqMhz * 10;
int nFreqU1 = (int)(g_dwDisplayClock / 100000) - nFactor1;
int nFactor2 = (nFactor1 + nFreqU1) * 10;
int nFreqU2 = (int)(g_dwDisplayClock / 10000) - nFactor2;
int nFactor3 = (nFactor2 + nFreqU2) * 10;
int nFreqU3 = (int)(g_dwDisplayClock / 1000) - nFactor3;
int nFactor4 = (nFactor3 + nFreqU3) * 10;
int nFreqU4 = (int)(g_dwDisplayClock / 100) - nFactor4;
int nFactor5 = (nFactor4 + nFreqU4) * 10;
int nFreqU5 = (int)(g_dwDisplayClock / 10) - nFactor5;
int nFactor6 = (nFactor5 + nFreqU5) * 10;
int nFreqU6 = (int)g_dwDisplayClock - nFactor6;
RETAILMSG(1, (TEXT("AMADisp: HD64404 Standard Display Driver %s\r\n"),
g_szVersionString));
RETAILMSG(1, (TEXT("AMADisp: %dx%d for %d.%d%d%d%d%d%dMHz DOTCK, %s\r\n"),
AMADispMode[0].gpeMode.width,
AMADispMode[0].gpeMode.height,
nFreqMhz, nFreqU1, nFreqU2, nFreqU3, nFreqU4, nFreqU5, nFreqU6,
g_szModeString));
m_pHD64404Regs = NULL;
m_pDisplayOutRegs = NULL;
m_pGraphicsEngineRegs = NULL;
m_pMPXIFRegs = NULL;
// virtual address allocation for all HD64404 registers
m_pHD64404Regs = (volatile unsigned long*)
VirtualAlloc(0, HD64404_REGSIZE, MEM_RESERVE, PAGE_NOACCESS);
if (m_pHD64404Regs == NULL) {
RETAILMSG(1,
(TEXT("AMADisp: VitualAlloc (HD64404 registers) failed.\r\n")));
goto ERROR0;
}
// virtual address mapping for all HD64404 registers
if (!VirtualCopy((PVOID)m_pHD64404Regs, (PVOID)g_dwRegisterAddress,
HD64404_REGSIZE, PAGE_READWRITE|PAGE_NOCACHE)) {
RETAILMSG(1,
(TEXT("AMADisp: VirtualCopy (HD64404 registers) failed.\r\n")));
goto ERROR1;
}
m_pDisplayOutRegs = (volatile unsigned long*)
((DWORD)m_pHD64404Regs + HD64404_DISPLAYOUT_OFFSET);
m_pGraphicsEngineRegs = (volatile unsigned long*)
((DWORD)m_pHD64404Regs + HD64404_GE_OFFSET);
m_pMPXIFRegs = (volatile unsigned long*)
((DWORD)m_pHD64404Regs + HD64404_MPXIF_OFFSET);
// virtual address allocation for total video memory
m_pVideoMemory = (volatile unsigned char*)
VirtualAlloc(0, g_dwVideoMemorySize, MEM_RESERVE, PAGE_NOACCESS);
if (m_pVideoMemory == NULL) {
RETAILMSG(1,
(TEXT("AMADisp: VitualAlloc (video memory) failed.\r\n")));
goto ERROR1;
}
// virtual address mapping for total video memory
if (!VirtualCopy((PVOID)m_pVideoMemory,
(PVOID)(g_dwLocalMemoryAddress + g_dwVideoMemoryOffset),
g_dwVideoMemorySize, PAGE_READWRITE|PAGE_NOCACHE)) {
RETAILMSG(1,
(TEXT("VirtualCopy (video memory) failed.\r\n")));
goto ERROR2;
}
/* Setup cursor pattern base pointer. Note that cursor pattern is */
/* stored in linear-converted tiled space, so address bit swapping */
/* is required to access actual cursor pattern from CPU. */
/* This driver is using cursor 1 for mouse pointer with blink */
/* enabled. Blink function displays Pattern A and B alternatively */
/* or turn on and off Pattern A in specified term. */
m_pCursorPattern = (volatile unsigned char*)
((DWORD)m_pVideoMemory + g_dwCursorAreaOffset
- g_dwVideoMemoryOffset); // Need to cancel video memory offset
// Get BusyWait loop count multiplier used in power handler.
g_dwLoop1ms = AdjustMicroSecondsToLoopCount(1000);
return;
ERROR2:
VirtualFree((LPVOID)m_pVideoMemory, 0, MEM_RELEASE);
ERROR1:
VirtualFree((LPVOID)m_pHD64404Regs, 0, MEM_RELEASE);
ERROR0:
return;
}
#define PCG_PGM_BITS 22
#define SendPCGCommand(numBits, Data) \
if (1) { \
DWORD dwVal = *pdwDataOut; \
int i, d; \
d = Data; \
dwVal &= 0xFFFFFF9F; \
for (i = 0; i < numBits; i++) { \
if (d & 1) dwVal |= 0x40; \
else dwVal &= 0xFFFFFFBF; \
*pdwDataOut = dwVal; /* set data with SCLK low */\
BusyWait(AdjustMicroSecondsToLoopCount(1)); \
*pdwDataOut = dwVal | 0x20; /* generate rising SCLK edge */\
BusyWait(AdjustMicroSecondsToLoopCount(1)); \
*pdwDataOut = dwVal; /* generate falling SCLK edge */\
d >>= 1; \
} \
} \
else /* This 'else' catches trailing semicolon. */
BOOL AMADisp::SetClock(int nModeId)
{
volatile unsigned long* pdwGPIORegs;
volatile unsigned long* pdwDirection;
volatile unsigned long* pdwDataOut;
volatile unsigned long* pdwInactive;
HANDLE hGPIOEvent;
DWORD dwData, dwWork;
PBYTE pRegs;
BOOL bRet; // return value
POWER_CONTROL_CONFIG pwc; // power control, used for GPIO module
int nOnes, nBits;
int nRP, nWP; // read position and write position
// This clock initialization is only for display clock mode 2 using
// ICD2053B Programmable Clock Generator. If the ICD2053B PCG parameters
// are all 0, this is treated as mode 0/1 and just return with TRUE.
pRegs = AMADispMode[nModeId].PCGRegs;
if (pRegs[PCG_P] == 0 && pRegs[PCG_D] == 0 && pRegs[PCG_M] == 0
&& pRegs[PCG_Q] == 0 && pRegs[PCG_I] == 0) {
// Do not touch, may be no hardware.
return TRUE;
}
pdwGPIORegs = (volatile unsigned long*)
((DWORD)m_pHD64404Regs + HD64404_GPIO0_OFFSET);
pdwDirection = (volatile unsigned long*)
((DWORD)pdwGPIORegs + GPIO_DIRECTION_OFFSET);
pdwDataOut = (volatile unsigned long*)
((DWORD)pdwGPIORegs + GPIO_DATAOUT_OFFSET);
pdwInactive = (volatile unsigned long*)
((DWORD)pdwGPIORegs + GPIO_INACTIVE_OFFSET);
hGPIOEvent = CreateEvent(
NULL, FALSE, FALSE, HD64404_GPIO0_EVENT_NAME); // auto reset
if (hGPIOEvent == NULL) {
RETAILMSG(1,
(TEXT("Event creation failed. (GPIO0 protection)\r\n")));
return FALSE;
}
if (GetLastError() != ERROR_ALREADY_EXISTS) {
// No one has created this GPIO0 event. This means no one has
// initialized GPIO0 so the initialization is required for it.
// Set the new event to "signaled" state.
SetEvent(hGPIOEvent);
}
// Check '111' pattern in data bits and insert a 0 after it.
nOnes = 0; // How many 1's appeared continuously
nBits = PCG_PGM_BITS;
nRP = 0;
nWP = 0;
dwData = 0;
dwWork = pRegs[PCG_P] << 15 | pRegs[PCG_D] << 14 | pRegs[PCG_M] << 11
| pRegs[PCG_Q] << 4 | pRegs[PCG_I];
while (nRP < PCG_PGM_BITS) {
if ((dwWork >> nRP) & 1) {
dwData |= 0x01 << nWP; // set a bit at current position
nOnes++;
if (nOnes >= 3) { // insert a 0 after '111'.
nOnes = 0;
nBits++;
nWP++; // skip current write position
}
}
else nOnes = 0; // reset continuous 1's counter
nRP++;
nWP++;
}
DEBUGMSG(GPE_ZONE_HW,
(TEXT("AMADisp: ICD2053B programming data = %x.(%d bits)\r\n"),
dwData, nBits));
// Send command bits to programmable clock generator ICD2053B.
// In the HD64404 I/O board of S1-E, ICD2053B SCLK is controlled by
// HD64404 GPIO5, and ICD2053B DATA is controlled by HD64404 GPIO6.
// However _MUXREF/OE is connected to GPIO7, but this pin is tri-stated.
__try {
// Wait 10 seconds max to get GPIO mutual protection event.
if (WaitForSingleObject(hGPIOEvent, 10000) != WAIT_OBJECT_0) {
RETAILMSG(1,
(TEXT("AMADisp: Failed to get GPIO0 event.\r\n")));
bRet = FALSE;
__leave;
}
else {
// Turns on clock for GPIO module.
memset((PVOID)&pwc, 0, sizeof(POWER_CONTROL_CONFIG));
pwc.bValidCControl1 = TRUE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -