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

📄 lpc32xx_lcd.cpp

📁 NXP LPC3000系列 wince BSP包
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    // green not swapped
	if (LCDPanelList[PanelType].bits_per_pixel == 16) {
		tmp = CLCDC_LCDCTRL_BPP16_565;
	}
	else
	{
		tmp = CLCDC_LCDCTRL_BPP24;
	}
    pLCDRegs->lcdctrl = (tmp | CLCDC_LCDCTRL_RGB | CLCDC_LCDCTRL_TFT);

    // Setup up display mode related constants
    m_nScreenWidth = LCDPanelList[PanelType].pixels_per_line;
    m_nScreenHeight = LCDPanelList[PanelType].lines_per_panel;
    m_colorDepth = LCDPanelList[PanelType].bits_per_pixel;
    m_cbScanLineLength = LCDPanelList[PanelType].pixels_per_line * bsize;
    m_FrameBufferSize = m_nScreenHeight * m_cbScanLineLength;

	// Allocate virtual memory for frame buffer
    m_VirtualFrameBuffer = (DWORD) VirtualAlloc(NULL, m_FrameBufferSize,
		MEM_RESERVE, (PAGE_READWRITE | PAGE_NOCACHE));
    if (!m_VirtualFrameBuffer)
    {
        RETAILMSG(1, (TEXT("m_VirtualFrameBuffer is not allocated\n\r")));
        return;
    }

	// Setup frame buffer
	phya = IMAGE_WINCE_LCD_BUFFERS_PA;
	if ((UseIRAM == 1) && (m_FrameBufferSize <= (256 * 1024)))
	{
		phya = DEVICE_IRAM_PA;
        RETAILMSG(1, (TEXT("Using IRAM for LCD buffer\n\r")));
	}

	if (!VirtualCopy((PVOID)m_VirtualFrameBuffer, (PVOID) (phya >> 8),
		m_FrameBufferSize, (PAGE_READWRITE | PAGE_NOCACHE | PAGE_PHYSICAL)))
   {
	    RETAILMSG(1, (TEXT("m_VirtualFrameBuffer is not mapped\n\r")));
        VirtualFree((PVOID)m_VirtualFrameBuffer, 0, MEM_RELEASE);
	    return;
    }

	// Enable LCD
	pLCDRegs->lcdupbase = phya;
	pLCDRegs->lcdctrl |= (CLCDC_LCDCTRL_ENABLE | CLCDC_LCDCTRL_PWR);

	// Enable LCD and backlight power
    pa.QuadPart = GPIO_BASE;
	pGPIOREGs = (GPIO_REGS_T *) MmMapIoSpace(pa, sizeof (GPIO_REGS_T), FALSE);
	pGPIOREGs->pio_outp_set = _BIT(0);
#if BSP_BOARD_PHY3250_QVGA_LCD1307 > 0
	pGPIOREGs->pio_outp_set = _BIT(4);
#else
	pGPIOREGs->pio_outp_clr = _BIT(4);
#endif
    MmUnmapIoSpace((PVOID) pGPIOREGs, 0);

    DEBUGMSG(1, (TEXT("m_VirtualFrameBuffer is mapped at %x(PHY : %x)\n\r"),
		m_VirtualFrameBuffer, phya));
#endif
}

//------------------------------------------------------------------------------
//
//  Constructor
//
LPC32XXLCD::LPC32XXLCD()
{
    DEBUGMSG(ZONE_FUNCTION, (TEXT("LPC32XXLCD::LPC32XXLCD\r\n")));

	// Initialize hardware
	lpc32xx_hw_init();

    // setup ModeInfo structure
    m_gpeMode.modeId = 0;
    m_gpeMode.width = m_nScreenWidth;
    m_gpeMode.height = m_nScreenHeight;
	if (LCDPanelList[PanelType].bits_per_pixel == 16) {
		m_gpeMode.format = gpe16Bpp;
	}
	else
	{
		m_gpeMode.format = gpe24Bpp;
	}
    m_gpeMode.Bpp = m_colorDepth;
    m_gpeMode.frequency = 60;
    m_pMode = &m_gpeMode;

	// Allocate display surface
    m_pPrimarySurface = new GPESurf(m_nScreenWidth, m_nScreenHeight,
		(void*)(m_VirtualFrameBuffer), m_cbScanLineLength, m_gpeMode.format); 
    if (m_pPrimarySurface)
    {
        memset ((void*)m_pPrimarySurface->Buffer(), 0x0, m_FrameBufferSize);
    }

	m_cursorVisible = FALSE;
    m_cursorDisabled = TRUE;
    m_cursorForcedOff = FALSE;
    memset(&m_cursorRect, 0x0, sizeof(m_cursorRect));
    m_cursorStore = NULL;
    m_cursorXor = NULL;
    m_cursorAnd = NULL;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("--LPC32XXLCD::LPC32XXLCD\r\n")));
}

//------------------------------------------------------------------------------
//
//  Dectructor
//
LPC32XXLCD::~LPC32XXLCD()
{
    delete [] m_cursorStore; m_cursorStore = NULL;
    delete [] m_cursorXor; m_cursorXor = NULL;
    delete [] m_cursorAnd; m_cursorAnd = NULL;

//	lpc32xx_hw_deinit();
}

//------------------------------------------------------------------------------
//
//  Method:  NumModes
//
//  This method returns number of modes supported by display.
//
int LPC32XXLCD::NumModes()
{
    DEBUGMSG(ZONE_FUNCTION, (L"+LPC32XXLCD::NumModes()\r\n"));
    return 1;
}

//------------------------------------------------------------------------------
//
//  Method:  GetModeInfo
//
//  This method returns mode information for mode number of modes supported
//  by display.
//
SCODE LPC32XXLCD::GetModeInfo(GPEMode* pMode, int modeNumber)
{
    DEBUGMSG(ZONE_FUNCTION, (TEXT("++LPC32XXLCD::GetModeInfo\r\n")));
    
    if (modeNumber != 0)
    {
        return E_INVALIDARG;
    }
    
    *pMode = m_gpeMode;
    
    DEBUGMSG(ZONE_FUNCTION, (TEXT("--LPC32XXLCD::GetModeInfo\r\n")));
    
    return S_OK;
}

//------------------------------------------------------------------------------
//
//  Method:  SetMode
//
//  This method should set display hardware to given mode.
//
SCODE LPC32XXLCD::SetMode(int modeNumber, HPALETTE *pPalette)
{
    DEBUGMSG(ZONE_FUNCTION, (TEXT("++LPC32XXLCD::SetMode\r\n")));

    if (modeNumber != 0)
    {
        DEBUGMSG(ZONE_WARN, (TEXT("LPC32XXLCD::SetMode Want mode %d, only have mode 0\r\n"),
			modeNumber));
        return  E_INVALIDARG;
    }

    if (pPalette)
    {
        *pPalette = EngCreatePalette (PAL_BITFIELDS, 0, NULL, 
            LCDPanelList[PanelType].m_BitMasks[0], LCDPanelList[PanelType].m_BitMasks[1],
			LCDPanelList[PanelType].m_BitMasks[2]);
    }

    DEBUGMSG(ZONE_FUNCTION, (TEXT("--LPC32XXLCD::SetMode\r\n")));
    
    return S_OK;
}

//------------------------------------------------------------------------------
//
//  Method:  AllocSurface
//
//  This method executes when the driver must allocate storage for surface
//  pixels. In our case there isn't video memory which can be used for this
//  purpose. In case that video memory is required we should fail call
//  otherwise normal memory chunk will be allocated.
//
SCODE LPC32XXLCD::AllocSurface(
    GPESurf **ppSurf, int width, int height, EGPEFormat format, int flags
) {
    SCODE sc = S_OK;

    // There isn't extra video memory, so fail if it is required
    if ((flags & GPE_REQUIRE_VIDEO_MEMORY) != 0) {
        DEBUGMSG(ZONE_ERROR, (L"LPC32XXLCD::AllocSurface: "
            L"Flat display driver can't allocate extra video memory\r\n"
        ));
        *ppSurf = NULL;
        sc = E_OUTOFMEMORY;
        goto cleanUp;
    }

    // Allocate surface and check result
    *ppSurf = new GPESurf(width, height, format);
    if (*ppSurf == NULL || (*ppSurf)->Buffer() == NULL) {
        DEBUGMSG(ZONE_ERROR, (L"LPC32XXLCD::AllocSurface: "
            L"Failed allocate surface (width: %d, height: %d, format %d\r\n",
            width, height, format
        ));
        delete *ppSurf; *ppSurf = NULL;
        sc = E_OUTOFMEMORY;
        goto cleanUp;
    }
    
cleanUp:
    return sc;
}

//------------------------------------------------------------------------------
//
//  Method: WrapperEmulatedLine
//
//  This function is wrapped around emulated line implementation. It must
//  be implemented only if software pointer is used. It switch off/on cursor
//  if line cross it.
//
SCODE LPC32XXLCD::WrappedEmulatedLine (GPELineParms *lineParameters)
{
    SCODE sc;
    RECT bounds;
    int N_plus_1;

    // If cursor is on check for line overlap
    if (m_cursorVisible && !m_cursorDisabled) {

        // Calculate the bounding-rect to determine overlap with cursor
        if (lineParameters->dN) {
            // The line has a diagonal component
            N_plus_1 = 2 + (
                (lineParameters->cPels * lineParameters->dN)/lineParameters->dM
            );
        } else {
            N_plus_1 = 1;
        }

        switch (lineParameters->iDir) {
        case 0:
            bounds.left = lineParameters->xStart;
            bounds.top = lineParameters->yStart;
            bounds.right = lineParameters->xStart + lineParameters->cPels + 1;
            bounds.bottom = bounds.top + N_plus_1;
            break;
        case 1:
            bounds.left = lineParameters->xStart;
            bounds.top = lineParameters->yStart;
            bounds.bottom = lineParameters->yStart + lineParameters->cPels + 1;
            bounds.right = bounds.left + N_plus_1;
            break;
        case 2:
            bounds.right = lineParameters->xStart + 1;
            bounds.top = lineParameters->yStart;
            bounds.bottom = lineParameters->yStart + lineParameters->cPels + 1;
            bounds.left = bounds.right - N_plus_1;
            break;
        case 3:
            bounds.right = lineParameters->xStart + 1;
            bounds.top = lineParameters->yStart;
            bounds.left = lineParameters->xStart - lineParameters->cPels;
            bounds.bottom = bounds.top + N_plus_1;
            break;
        case 4:
            bounds.right = lineParameters->xStart + 1;
            bounds.bottom = lineParameters->yStart + 1;
            bounds.left = lineParameters->xStart - lineParameters->cPels;
            bounds.top = bounds.bottom - N_plus_1;
            break;
        case 5:
            bounds.right = lineParameters->xStart + 1;
            bounds.bottom = lineParameters->yStart + 1;
            bounds.top = lineParameters->yStart - lineParameters->cPels;
            bounds.left = bounds.right - N_plus_1;
            break;
        case 6:
            bounds.left = lineParameters->xStart;
            bounds.bottom = lineParameters->yStart + 1;
            bounds.top = lineParameters->yStart - lineParameters->cPels;
            bounds.right = bounds.left + N_plus_1;
            break;
        case 7:
            bounds.left = lineParameters->xStart;
            bounds.bottom = lineParameters->yStart + 1;
            bounds.right = lineParameters->xStart + lineParameters->cPels + 1;
            bounds.top = bounds.bottom - N_plus_1;
            break;
        default:
            DEBUGMSG(ZONE_WARN, (L"LPC32XXLCD::WrappedEmulatedLine: "
                L"Invalid direction: %d\r\n", lineParameters->iDir));
            sc = E_INVALIDARG;
            goto cleanUp;
        }

        // If line overlap cursor, turn if off
        RECTL cursorRect = m_cursorRect;
        RotateRectl (&cursorRect);

        if (cursorRect.top < bounds.bottom && 
            cursorRect.bottom > bounds.top &&
            cursorRect.left < bounds.right && 
            cursorRect.right > bounds.left
        ) { 
            CursorOff();
            m_cursorForcedOff = TRUE;
        }            
    }

    // Do emulated line
    sc = EmulatedLine(lineParameters);

    // If cursor was forced off turn it back on
    if (m_cursorForcedOff) {
        m_cursorForcedOff = FALSE;
        CursorOn();
    }

cleanUp:
    return sc;
}

//------------------------------------------------------------------------------
//
//  Method: Line
//
//  This method executes before and after a sequence of line segments,
//  which are drawn as a path. It examines the line parameters to determine
//  whether the operation can be accelerated. It also places a pointer to
//  a function to execute once per line segment into the pLine member
//  of the GPELineParms structure.
//
SCODE LPC32XXLCD::Line(GPELineParms *pLineParms, EGPEPhase phase)
{
    if (phase == gpeSingle || phase == gpePrepare) {
        if ((pLineParms->pDst != m_pPrimarySurface)) {
            pLineParms->pLine = &GPE::EmulatedLine;
        } else {
            pLineParms->pLine = 
				(SCODE (GPE::*)(struct GPELineParms *))&LPC32XXLCD::WrappedEmulatedLine;
        }            
    }
    return S_OK;
}

//------------------------------------------------------------------------------
//
//  Method:  BltPrepare
//
//  This method identifies the appropriate functions needed to perform
//  individual blits. This function executes before a sequence of clipped blit
//  operations.
//
SCODE LPC32XXLCD::BltPrepare(GPEBltParms *pBltParms)
{
    RECTL rect;
    LONG swapTmp;

	pBltParms->pBlt = &LPC32XXLCD::EmulatedBlt;

    // Check if destination overlap with cursor
    if (
        pBltParms->pDst == m_pPrimarySurface &&
        m_cursorVisible && !m_cursorDisabled
    ) { 
        if (pBltParms->prclDst != NULL) {
            rect = *pBltParms->prclDst;     // if so, use it

            // There is no guarantee of a well
            // ordered rect in blitParamters
            // due to flipping and mirroring.
            if (rect.top > rect.bottom) {
                swapTmp = rect.top;
                rect.top = rect.bottom;
                rect.bottom = swapTmp;
            }
            if (rect.left > rect.right) {
                swapTmp    = rect.left;
                rect.left  = rect.right;
                rect.right = swapTmp;
            }
        } else {
            rect = m_cursorRect;
        }

        // Turn off cursor if it overlap
        if (
            m_cursorRect.top <= rect.bottom &&
            m_cursorRect.bottom >= rect.top &&
            m_cursorRect.left <= rect.right &&
            m_cursorRect.right >= rect.left
        ) {

⌨️ 快捷键说明

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