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

📄 ddlcdc.cpp

📁 Microsoft WinCE 6.0 BSP FINAL release source code for use with the i.MX27ADS TO2 WCE600_FINAL_MX27_S
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    if(m_pMode->modeId == DISPLAY_MODE_SHPQVGA)   // SHARP
    {
        m_bTVModeActive = FALSE;
        m_nPanelTYPE = 0;
    }
    if(m_pMode->modeId == DISPLAY_MODE_NECVGA)    // NEC
    {
        m_bTVModeActive = FALSE;
        m_nPanelTYPE = 1;
    }
    if(m_pMode->modeId == DISPLAY_MODE_PAL)
    {
        m_bTVModeActive = TRUE;
        m_bTVNTSCOut = FALSE;           //PAL
    }
    if(m_pMode->modeId == DISPLAY_MODE_NTSC)
    {
        m_bTVModeActive = TRUE;
        m_bTVNTSCOut = TRUE;            //NTSC
    }

    if(!bModeGot)
    {
        // No suitable display mode found, default display mode is used
        DEBUGMSG(GPE_ZONE_INIT, (TEXT("MX27DDLcdc Init: Default display mode is used!\r\n")));
        m_nScreenWidth  = m_pMode->width;
        m_nScreenHeight = m_pMode->height;
        m_nScreenBpp    = m_pMode->Bpp;
    }

    // Setup surface alignment as required by the LCDC of i.MX27 for 4 bytes
    m_nSurfacePixelAlign = 4 / (m_pMode->Bpp / 8);
    
    // Sanity Check for screen width
    if(m_pMode->width & (m_nSurfacePixelAlign - 1))
    {
        DEBUGMSG(GPE_ZONE_ERROR, (TEXT("MX27DDLcdc Init: Screen width (%d) is not aligned for %d bytes!\r\n"), m_pMode->width, m_nSurfacePixelAlign));
        result = FALSE;
        goto _done;
    }

    // The line stride of i.MX27 LCDC is 32-bits (4 bytes) aligned
    m_nScreenStride = ((m_nScreenWidth * (m_nScreenBpp / 8) + 3) >> 2) << 2;

    DEBUGMSG(GPE_ZONE_INIT, (TEXT("MX27DDLcdc Init: Current display mode:\r\n")));
    DEBUGMSG(GPE_ZONE_INIT, (TEXT("\t\tm_nScreenWidth:  %d\r\n"), m_nScreenWidth));
    DEBUGMSG(GPE_ZONE_INIT, (TEXT("\t\tm_nScreenHeight: %d\r\n"), m_nScreenHeight));
    DEBUGMSG(GPE_ZONE_INIT, (TEXT("\t\tm_nScreenStride: %d\r\n"), m_nScreenStride));
    DEBUGMSG(GPE_ZONE_INIT, (TEXT("\t\tm_nScreenBpp:    %d\r\n"), m_nScreenBpp));

    // Setup other DDGPE mode informations
    nBPP = m_pMode->Bpp/8 - 1;
    switch (m_pMode->Bpp)
    {
        case    8:
        case    16:
        case    24:
        case    32:
            m_pModeEx->ePixelFormat = ePixelFormat[nBPP];
            m_pModeEx->lPitch = m_nScreenStride;
            m_pModeEx->dwRBitMask = BitMasks[nBPP][0];
            m_pModeEx->dwGBitMask = BitMasks[nBPP][1];
            m_pModeEx->dwBBitMask = BitMasks[nBPP][2];
            break;

        default:
            DEBUGMSG(GPE_ZONE_ERROR,(TEXT("MX27DDLcdc Init: Invalid BPP value passed to driver - Bpp = %d\r\n"), m_pMode->Bpp));
            m_pMode->format = gpeUndefined;
            result = FALSE;
            goto _done;
    }

    // Setup Rotation
    m_nScreenHeightSave = m_pMode->height;
    m_nScreenWidthSave = m_pMode->width;
    m_iRotate = GetRotateModeFromReg();
    SetRotateParams();

    m_nScreenWidth = m_pMode->width;
    m_nScreenHeight = m_pMode->height;


    // Pre-initialize the graphic window operator for overlay
    m_pOverlaySurfaceOp = (pOverlaySurf_t)malloc(sizeof(overlaySurf_t));
    if(m_pOverlaySurfaceOp)
    {
        memset(m_pOverlaySurfaceOp, 0x00, sizeof(overlaySurf_t));
    }
    else
    {
        DEBUGMSG(GPE_ZONE_ERROR, (TEXT("MX27DDLcdc Init: failed to allocate memory for graphic windower operator, error(%d)\r\n"), GetLastError()));
        result = FALSE;
        goto _done;
    }
    
_done:  
    DEBUGMSG(GPE_ZONE_INIT, (TEXT("MX27DDLcdc Init %s.\r\n"), result ? L"succeeds" : L"fails"));
    return result;
}


//------------------------------------------------------------------------------
//
// Function: InitHardware
//
// Initialize the hardware resources for the driver.
//
// Parameters:
//      None.
//
// Returns:
//      TRUE           successful
//      FALSE          failed
//
//------------------------------------------------------------------------------
BOOL MX27DDLcdc::InitHardware(VOID)
{
    BOOL result = TRUE;
    PHYSICAL_ADDRESS phyAddr;

    //Mem maps the LCDC module space for user access
    phyAddr.QuadPart = CSP_BASE_REG_PA_LCDC;
    m_pLcdcReg = (CSP_LCDC_REGS *)MmMapIoSpace(phyAddr, sizeof(CSP_LCDC_REGS), FALSE);
    if (m_pLcdcReg  ==  NULL)   
    {
        DEBUGMSG (GPE_ZONE_ERROR, (TEXT("LcdcClass: VirtualAlloc failed!\r\n")) );
        result = FALSE;
        goto _done;
    }

    // Initialze LCDC interrupt
    m_hSyncEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    if(NULL == m_hSyncEvent)
    {
        DEBUGMSG(GPE_ZONE_ERROR, (TEXT("MX27DDLcdc InitHardware: fail to create the intr event, error[%d]!\r\n"), GetLastError()));
        result = FALSE;
        goto _done;
    }

    DWORD irq = IRQ_LCDC;
    if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &irq, sizeof(DWORD),
                        &g_dwlcdcSysintr, sizeof(DWORD), NULL)){
                DEBUGMSG(GPE_ZONE_ERROR, (_T("Failed to obtain sysintr value!\r\n")));
        return 0;
    }

    if(!InterruptInitialize(g_dwlcdcSysintr, m_hSyncEvent, NULL, NULL))
    {
        DEBUGMSG(GPE_ZONE_ERROR, (TEXT("MX27DDLcdc InitHardware: fail to initialize the interrupt, error[%d]!\r\n"), GetLastError()));
        result = FALSE;
        goto _done;
    }

    m_hSyncThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)MX27DDLcdcIntr, this, 0, NULL);
    if(NULL == m_hSyncThread)
    {
        DEBUGMSG(GPE_ZONE_ERROR, (TEXT("MX27DDLcdc InitHardware: fail to initiate the interrupt thread, error[%d]!\r\n"), GetLastError()));
        result = FALSE;
        goto _done;
    }

    // Initialze a critical section to protect interrupt status flag update violation
    InitializeCriticalSection(&m_CriticalSection);

    // Configure LCDC of i.MX27 processor
    if(!SetModeHardware(m_pMode->modeId))
    {
        DEBUGMSG(GPE_ZONE_ERROR, (TEXT("MX27DDLcdc InitHardware: fail to initialize hardware!\r\n"), GetLastError()));
        result = FALSE;
        goto _done;
    }

_done:

    return result;
}


//------------------------------------------------------------------------------
//
// Function: SetupVideoMemory
//
// Setup the video memory buffer and other related buffers.
//
// Parameters:
//      None.
//
// Returns:
//      TRUE            successful
//      FALSE           failed
//
//------------------------------------------------------------------------------
BOOL MX27DDLcdc::SetupVideoMemory(VOID)
{
    SCODE sc;
    PHYSICAL_ADDRESS phyAddr;
    BOOL result = TRUE;
    DWORD iFrameSize = m_nScreenStride * m_nScreenHeightSave;

    // Allocate video memory
    /*
     * IMPORTANT: There is dedicated video memory for i.MX27 
     *            processor, therefore, we should not share from 
     *            system memory.
     */

   // The video memory should be more than three frame size:
      //    - one for primary surface // primary
      //    - one for a blank surface used when OS goes to power suspension // blank
      //    - one for general use in DirectDraw applications
    
    //iFrameSize = m_LcdcCtx.VideoFrameWidth * m_LcdcCtx.VideoFrameHight * BSPGetPixelSizeInByte();
    m_nVideoMemorySize = m_LcdcCtx.VideoMemorySize;
    //    m_nVideoMemorySize = max3(m_nVideoMemorySize, 3*iFrameSize, DEFAULT_VIDEO_MEM_SIZE);
    phyAddr.QuadPart = m_LcdcCtx.VideoMemoryPhyAdd;
    m_pVideoMemory = (UINT8 *)MmMapIoSpace(phyAddr, m_nVideoMemorySize, FALSE);
    if (m_pVideoMemory == NULL)
    {
        DEBUGMSG (GPE_ZONE_ERROR, (TEXT("Frame Buffer MmMapIoSpace failed!\r\n")) );
                result = FALSE;
                goto _done;
    }
    m_nLAWPhysical = m_LcdcCtx.VideoMemoryPhyAdd;
    
    //Allocate Frame Buffer Space in shared memory
    m_hLAWMapping = CreateFileMapping(
        INVALID_HANDLE_VALUE,
        NULL,
        PAGE_READWRITE,
        0,
        m_nVideoMemorySize,
        NULL);

    if (m_hLAWMapping != NULL) 
    {
        m_pLAW = (unsigned char *)MapViewOfFile(
            m_hLAWMapping,
            FILE_MAP_WRITE,
            0,
            0,
            0);
    } 
    else 
    {
        DEBUGMSG(GPE_ZONE_ERROR, (TEXT("MX27DDLcdc SetupVideoMemory: failed at MapViewOfFile(), error[%d]\r\n"), m_nVideoMemorySize, GetLastError()));
        result = FALSE;
        goto _done;
    }

    result = VirtualCopy(
        m_pLAW,
        (LPVOID)(m_nLAWPhysical >> 8),
        m_nVideoMemorySize,
        PAGE_READWRITE|PAGE_NOCACHE|PAGE_PHYSICAL);

    if(!result)
    {
        DEBUGMSG(GPE_ZONE_ERROR, (TEXT("MX27DDLcdc SetupVideoMemory: failed at VirtualCopy(), error[%d]\r\n"), m_nVideoMemorySize, GetLastError()));
        result = FALSE;
        goto _done;
    }

    // Create video memory heap
    if (!m_pVideoMemoryHeap)
        m_pVideoMemoryHeap = new SurfaceHeap(m_nVideoMemorySize, NULL, NULL, NULL);

    // Create primary surface and blank surface
    if (!m_pPrimarySurface)
    {
        if (FAILED(sc = AllocSurface((DDGPESurf **) &m_pPrimarySurface, m_nScreenWidthSave,
                m_nScreenHeightSave, m_pMode->format, m_pModeEx->ePixelFormat,
                GPE_REQUIRE_VIDEO_MEMORY)))
        {
            DEBUGMSG(GPE_ZONE_ERROR, (TEXT("MX27DDLcdc SetMode: Couldn't allocate primary surface\r\n")));
            result = FALSE;
            goto _done;
        }
    }

    // Load freescale logo onto screen in case that the primary surface is not at the starting point of video memory.
    if(m_pPrimarySurface->OffsetInVideoMemory())
    {
        WaitForNotBusy();
        //LoadFreescaleLogo(m_pPrimarySurface);
    }
    
    m_pPrimarySurface->SetRotation(m_nScreenWidth, m_nScreenHeight, m_iRotate);
    
_done:
    
    if(result)
    {
        DEBUGMSG(GPE_ZONE_INIT, (TEXT("MX27DDLcdc SetupVideoMemory: \r\n")));
        DEBUGMSG(GPE_ZONE_INIT, (TEXT("\tVirtual address mapped access window: 0x%08x\r\n"), m_pLAW));
        DEBUGMSG(GPE_ZONE_INIT, (TEXT("\tVirtual address of video memory:      0x%08x\r\n"), m_pVideoMemory));
        DEBUGMSG(GPE_ZONE_INIT, (TEXT("\tPhysical address of video memory:     0x%08x\r\n"), m_LcdcCtx.VideoMemoryPhyAdd)); 
        DEBUGMSG(GPE_ZONE_INIT, (TEXT("\tSize:                                 0x%08x\r\n"), m_nVideoMemorySize));
    }

    return result;
}


//------------------------------------------------------------------------------
//
//  FUNCTION:     SetModeHardware
//
//  DESCRIPTION:  Setup hardware LCDC for current display mode
//
//  PARAMETERS:     
//
//  RETURNS:
//                TRUE: successful
//                FALSE: failed
//
//------------------------------------------------------------------------------
BOOL MX27DDLcdc::SetModeHardware(int modeNo)
{
    BOOL result = FALSE;
  
    if(!InitializeLCDC(m_bTVModeActive, m_bTVNTSCOut, m_nPanelTYPE))
    {
        DEBUGMSG(1, (TEXT("InitializeLCDC Failed")));
        goto _done;     
    }

    // Pre-setup framebuffer address

    // Load Freescale logo at the starting point of the video memory
    //LoadFreescaleLogo(m_pLAW);

    result = TRUE;

_done:
    return result;
}


//------------------------------------------------------------------------------
//
// Function: Cleanup
//
// Release all resouces for either failed initialization
// or driver unloading.
//
// Parameters:
//      None.
//
// Returns:
//      None.
//
//------------------------------------------------------------------------------
VOID MX27DDLcdc::Cleanup(VOID)
{
    DDK_GPIO_CFG cfg;

    m_nMask = 0;   // for flicker

    BSPTurnOffLCD();

    BSPDeinitLCDC(&m_LcdcCtx);

    // Release LCDC register map
    if(m_pLcdcReg)
    {
        // disable LCDC
        INSREG32BF(&m_pLcdcReg->RMCR, LCDC_RMCR_SELF_REF, LCDC_RMCR_SELF_REF_DISABLE);

        MmUnmapIoSpace(m_pLcdcReg, sizeof(CSP_LCDC_REGS));
        m_pLcdcReg  =   NULL;
    }

    // Disable LCDC module pins
    DDK_GPIO_SET_CONFIG(cfg, LCDC);
    DDKGpioDisable(&cfg);

    // Disable LCDC hw clocks
    DDKClockSetGatingMode(DDK_CLOCK_GATE_INDEX_LCDC, DDK_CLOCK_GATE_MODE_DISABLE);

    // Destroy surface objects
    if(m_pPrimarySurface)
    {
        delete m_pPrimarySurface;
        m_pPrimarySurface = NULL;
    }
    if(m_pBlankSurface)
    {
        delete m_pBlankSurface;
        m_pBlankSurface = NULL;
    }

    // Release the shared vidoe memory
    if (m_pLAW)
    {
        UnmapViewOfFile(m_pLAW);
        m_pLAW = NULL;
    }
    if (m_hLAWMapping)
    {
        CloseHandle(m_hLAWMapping);
        m_hLAWMapping = NULL;
    }

    //Not need release memory because of reserved physical memory
    /*
    // Release video memory
    if(m_pVideoMemory)
    {
        FreePhysMem(m_pVideoMemory);
        m_pVideoMemory = NULL;
    }
    */

    // Release the overlay operator
    if(m_pOverlaySurfaceOp)
    {
        free(m_pOverlaySurfaceOp);
        m_pOverlaySurfaceOp = NULL;
    }

    // Disable interrupt source and release interrupt event
    InterruptDisable(g_dwlcdcSysintr);

    // Release SYSINTR
    KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR, &g_dwlcdcSysintr, sizeof(DWORD), NULL, 0, NULL);
    g_dwlcdcSysintr = SYSINTR_UNDEFINED;
    
    if(m_hSyncEvent)
    {
        CloseHandle(m_hSyncEvent);
        m_hSyncEvent= NULL;
    }

    // Terminate interrupt thread
    if(m_hSyncThread)
    {
        TerminateThread(m_hSyncThread, 0);
        CloseHandle(m_hSyncThread);
        m_hSyncThread = NULL;
    }

    DeleteCriticalSection(&m_CriticalSection);
}


//------------------------------------------------------------------------------
//
//  FUNCTION:       IntrProc
//
//  DESCRIPTION:    This function is interrupt handler.
//
//  NOTE:
//
//  PARAMETERS: 
//
//  RETURNS:        
//                  A double word value for ExitThread()
//
//------------------------------------------------------------------------------
DWORD MX27DDLcdc::IntrProc(VOID)
{
    while(TRUE)
    {
        if (WaitForSingleObject(m_hSyncEvent, INFINITE) != WAIT_OBJECT_0)
        {
            DEBUGMSG(GPE_ZONE_ERROR, (TEXT("MX27DDLcdc IntrProc: interrupt error [%d]\r\n"), GetLastError()));
            continue;
        }

        EnterCriticalSection(&m_CriticalSection);
        m_nPreIntrStatus = m_pLcdcReg->ISR;
        LeaveCriticalSection(&m_CriticalSection);

        InterruptDone(g_dwlcdcSysintr);
    }

    return 0;
}


//------------------------------------------------------------------------------
//
//  FUNCTION:       MX27DDLcdcIntr
//
//  DESCRIPTION:    This function is entry point of the interrupt thread.
//
//  NOTE:
//
//  PARAMETERS: 
//
//  RETURNS:        
//                  A double word value for ExitThread()
//
//------------------------------------------------------------------------------
DWORD MX27DDLcdcIntr(MX27DDLcdc * pClass)
{
    pClass->IntrProc();

    // We shouldn't come to here
    DEBUGMSG(GPE_ZONE_ERROR, (TEXT("MX27DDLcdcIntr: Exiting interrupt thread... error[%d]\r\n"), GetLastError()));
    return 0;
}

⌨️ 快捷键说明

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