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

📄 amadisp.cpp

📁 Wince4.2 BSP for SH4 engineering development board
💻 CPP
📖 第 1 页 / 共 3 页
字号:

//
//      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 + -