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

📄 xllp_lcd.c

📁 Intel PXA270底层设备驱动代码
💻 C
📖 第 1 页 / 共 4 页
字号:
#ifndef NO_NH040526A
#define ENABLE_DEBUG_MESSAGES 0
#define ENABLE_LOG_MESSAGES 1
#if ENABLE_DEBUG_MESSAGES
#define DBGMSG(cond, pargs) NKDbgPrintfW pargs
#else
#define DBGMSG(cond, pargs) 0
#endif
#if ENABLE_LOG_MESSAGES
#define LOGMSG(cond, pargs) NKDbgPrintfW pargs 
#else
#define LOGMSG(cond, pargs) 0
#endif
#define LOGGING_ENABLED (ENABLE_DEBUG_MESSAGES || ENABLE_LOG_MESSAGES)
#if LOGGING_ENABLED
#include <windows.h>   // for NKDbgPrintfW()
#endif
#endif /* NH040526A */

#include "xllp_defs.h"
#include "xllp_serialization.h"
#include "xllp_lcd.h"
#include "xllp_gpio.h"
#include "xllp_ost.h"

#ifndef NO_NH040609_OVERLAY2_YUVHWFIX

#define OVERLAY_DELAY_DISABLE    1000
#define OVERLAY_DELAY_ENABLE    50

#define SPINSLEEP(millisecs) XllpOstDelayMilliSeconds(pOSTRegs, millisecs)
XLLP_OST_T *pOSTRegs = NULL;
#endif /* NH040609_OVERLAY2_YUVHWFIX */

const unsigned short LS022Q8DD06_DATA_SET_1[] = {
0x000F, 0x0101,     /*R15 = 0x01 - Command Reset */
0x0004, 0x0101,     /*R4  = 0x01 - Standby Mode */
0x0000, 0x0103,     /*R0  = 0x03 - 260K colors */
0x0001, 0x010A,     /*R1  = 0x0A - Horz Display Start Position Setting */
0x0002, 0x0102,     /*R2  = 0x02 - Vert Display Start Position Setting */
0x0009, 0x0100,     /*R9  = 0x00 - Normal Operation Mode */
0x000A, 0x0103,     /*R10 = 0x03 - Neg Voltage of Gate & driver Output = Vss */
0x0019, 0x011A,     /*R25 = 0x1A - DC/DC Step Setting */
0x001A, 0x0115,     /*R26 = 0x15 - DC/DC Frequency Setting */
0x001B, 0x0148,     /*R27 = 0x48 - Regulator Setting (OFF) */
0x001C, 0x0100,     /*R28 = 0x00 - Low Power Setting */
0x0021, 0x0110,     /*R33 = 0x10 - DC/DC Rise Setting */
0x0018, 0x0109,     /*R24 = 0x09 - DC/DC Operation ON (Only VDC2 is ON) */
0x0003, 0x0100,     /*R3  = 0x00 - Horz Available Pixels (240) */
0x0005, 0x0100,     /*R5  = 0x00 - Register to Change 8 Color Mode (260K colors) */
0x0006, 0x0124,     /*R6  = 0x24 - Reverse Scan, Common Output is ON */
0x0008, 0x010E,     /*R8  = 0x0E - Amplitude Driving Period Setting */
0x000B, 0x0105,     /*R11 = 0x05 - Decide Common Amplitude */
0x000C, 0x0100,     /*R12 = 0x00 - Common Center Setting */
0x0024, 0x0102,     /*R36 = 0X02 - Source Output Setting */
0x0025, 0x010E,     /*R37 = 0x0E - Source Output Setting */
0x0026, 0x0112,     /*R38 = 0x12 - Source Output Setting */ 
0x0027, 0x011E,     /*R39 = 0x1E - Source Output Setting */
0x0028, 0x0122,     /*R40 = 0x22 - Source Output Setting */
0x0029, 0x012E,     /*R41 = 0x2E - Source Output Setting */
0x002A, 0x0137,     /*R42 = 0x37 - Gate Driving Signal Setting */
0x002B, 0x013A,     /*R43 = 0x3A - Gate Driving Signal Setting */
0x002C, 0x0137,     /*R44 = 0x37 - Gate Driving Signal Setting */
0x002D, 0x013A,     /*R45 = 0x3A - Gate Driving Signal Setting */
0x002E, 0x0137,     /*R46 = 0x37 - Gate Driving Signal Setting */
0x002F, 0x013A,     /*R47 = 0x3A - Gate Driving Signal Setting */
0x0030, 0x0180,     /*R48 = 0x80 - Gate Driving Signal Setting */
0x0031, 0x0101,     /*R49 = 0x01 - Gate Driving Signal Setting */
0x0032, 0x0136,     /*R50 = 0x36 - Gate Driving Signal Setting */
0x0033, 0x0101      /*R51 = 0x01 - Dummy Line setting */
};

const unsigned short LS022Q8DD06_DATA_SET_2[] = {
0x0018, 0x0179,     /* R24 = 0x79 - Vss1, Vss2 and Vr are ON */
0x001B, 0x0149,     /* R27 = 0x49 - Vs Regulator is ON */
0x0018, 0x017F,     /* R24 = 0x7F - Vdd2 is ON (Voltage in gate ON)*/
0x0036, 0x0101,     /* R54 = 0x01 */
0x0006, 0x0125,     /* R6  = 0x25 - Switch to normal mode*/
0x0004, 0x0100,     /* R4  = 0x00 - Amplifier is normal power */
0x000C, 0x0152,     /* R12 = 0x52 - Release Standby Mode */
0x0021, 0x0100,     /* R33 = 0x00 */
0x0006, 0x0135      /* R6  = 0x35 - Enable the display */
};

XLLP_STATUS_T XllpLCDInit(P_XLLP_LCD_T pXllpLCD)
{
	XLLP_STATUS_T status = 0;

	if (pOSTRegs != (XLLP_OST_T *)pXllpLCD->OST)
		pOSTRegs = (XLLP_OST_T *)pXllpLCD->OST;
        DBGMSG(1,(TEXT("XllpLCDInit: pOSTRegs->x%08x\r\n"),pOSTRegs));
	
	// Initialize the GPIO registers for proper LCD Controller operation
	LCDSetupGPIOs(pXllpLCD);

	// Initialize the LCD Controller and frame descriptors
	LCDInitController(pXllpLCD);

	// Clear LCD Controller status register
	LCDClearStatusReg(pXllpLCD);

	// Enable the LCD controller
	LCDEnableController(pXllpLCD);

	// If required, load the default palette into palette ram
	// and feed this to the LCD controller.
	if(pXllpLCD->BPP < BPP_16)
	{
		XllpLCDLoadPalette(pXllpLCD);
	}

	return status;
}

void XllpLCDLoadPalette(P_XLLP_LCD_T pXllpLCD)
{	
	volatile LCDRegs *p_LCDRegs;

	p_LCDRegs = (LCDRegs *) pXllpLCD->LCDC;

	// Reconfigure the second frame descriptor so that when loaded,
	// this descriptor loops to itself.
	pXllpLCD->frameDescriptorCh0fd2->FDADR = LCD_FDADR(pXllpLCD->frameDescriptorCh0fd2->PHYSADDR);

	// Reconfigure the palette frame descriptor so that it loads the second frame descriptor
	pXllpLCD->frameDescriptorPalette->FDADR = LCD_FDADR(pXllpLCD->frameDescriptorCh0fd2->FDADR);
	pXllpLCD->frameDescriptorPalette->FSADR = LCD_FSADR(pXllpLCD->_PALETTE_BUFFER_BASE_PHYSICAL); 
	pXllpLCD->frameDescriptorPalette->FIDR  = LCD_FIDR(0);


	if ( (p_LCDRegs->OVL1C1 & LCD_O1EN) || (p_LCDRegs->OVL2C1 & LCD_O2EN)) 
	{
		// Overlays are enabled
		pXllpLCD->frameDescriptorPalette->LDCMD = LCD_Len(pXllpLCD->PaletteSize << 1) | LCD_Pal;
	} else
	{
		// Overlays are disabled
		pXllpLCD->frameDescriptorPalette->LDCMD = LCD_Len(pXllpLCD->PaletteSize) | LCD_Pal;
	}

	pXllpLCD->frameDescriptorPalette->PHYSADDR = LCD_FDADR(pXllpLCD->_PALETTE_FRAME_DESCRIPTOR_BASE_PHYSICAL);

	// Insert the palette descriptor into the descriptor chain to load the palette.
	// When this load completes, fd2 is automatically loaded next in the chain.  
	// fd2 now loops to itself and continues to load frame data.
	pXllpLCD->frameDescriptorCh0fd1->FDADR = LCD_FDADR(pXllpLCD->_PALETTE_FRAME_DESCRIPTOR_BASE_PHYSICAL);  	

	// swap frame descriptor pointers so that this operation is reversed the next time through
	pXllpLCD->frameDescriptorTemp	= pXllpLCD->frameDescriptorCh0fd1;
	pXllpLCD->frameDescriptorCh0fd1 = pXllpLCD->frameDescriptorCh0fd2;
	pXllpLCD->frameDescriptorCh0fd2 = pXllpLCD->frameDescriptorTemp;
}

void XllpLCDSuspend(P_XLLP_LCD_T pXllpLCD, int SuspendType)
{
    volatile unsigned int APB_Temp;
	volatile LCDRegs *p_LCDRegs;
	volatile XLLP_GPIO_T *p_GPIORegs;

	p_LCDRegs = (LCDRegs *) pXllpLCD->LCDC;
	p_GPIORegs = (XLLP_GPIO_T *) pXllpLCD->GPIO;

	switch(SuspendType)
	{
	case Suspend_Graceful:
		// Initiate power down sequence
		p_LCDRegs->LCCR0 |= LCD_DIS;

		// Wait for LDD bit to get set once the last DMA transfer has completed
		while(!(p_LCDRegs->LCSR0 & LCD_LDD));

		// Clear the sticky LDD bit
		p_LCDRegs->LCSR0 |= LCD_LDD;
		break;
	case Suspend_Immediate:
		p_LCDRegs->LCCR0 &= ~LCD_ENB;
		break;
	default :
		break;
	}

	// don't use lock/unlock here because system call may be unavailable.
	p_GPIORegs->GPCR0	= XLLP_GPIO_BIT_PWM_OUT0;

    //
    // Ensure GPIO writes that have posted complete
    //
    APB_Temp = p_GPIORegs->GPCR0;

}

void XllpLCDResume(P_XLLP_LCD_T pXllpLCD)
{
	XllpLCDInit(pXllpLCD);
}

void XllpLCDSetDisplayPage(P_XLLP_LCD_T pXllpLCD, int page)
{
	// Set the physical address of the frame buffer for all three frame descriptors
	// Make sure that you've initialized FrameBufferSize before calling this function either manually
	// or through a call to XllpLCDInit().
	pXllpLCD->CurrentPage = page;
	pXllpLCD->frameDescriptorCh0fd1->FSADR = LCD_FSADR(pXllpLCD->_FRAME_BUFFER_BASE_PHYSICAL + pXllpLCD->CurrentPage*pXllpLCD->FrameBufferSize);
	pXllpLCD->frameDescriptorCh0fd2->FSADR = LCD_FSADR(pXllpLCD->_FRAME_BUFFER_BASE_PHYSICAL + pXllpLCD->CurrentPage*pXllpLCD->FrameBufferSize);
	pXllpLCD->frameDescriptorCh1->FSADR = LCD_FSADR(pXllpLCD->_FRAME_BUFFER_BASE_PHYSICAL + pXllpLCD->CurrentPage*pXllpLCD->FrameBufferSize + (pXllpLCD->FrameBufferSize >> 1));
}

void LCDInitController(P_XLLP_LCD_T pXllpLCD)
{
	int i = 0;
	int BPP = 0;
	int PCD = 0;
	unsigned int CCCR_L = 0;
    volatile unsigned int APB_Temp;
	volatile LCDRegs *p_LCDRegs;
	volatile XLLP_CLKMGR_T *p_CLKRegs;
	volatile XLLP_SSPREGS_T *p_SSPRegs;
	volatile XLLP_GPIO_T *p_GPIORegs;
	XLLP_OST_T *p_OSTRegs;

	int LCLK = 0;

	p_LCDRegs = (LCDRegs *) pXllpLCD->LCDC;
	p_CLKRegs = (XLLP_CLKMGR_T *) pXllpLCD->CLKMan;
	p_GPIORegs = (XLLP_GPIO_T *) pXllpLCD->GPIO;
	p_OSTRegs = (XLLP_OST_T *) pXllpLCD->OST;
	p_SSPRegs = (XLLP_SSPREGS_T *) pXllpLCD->SSP;

	p_LCDRegs->LCCR0 = 0;
	p_LCDRegs->LCCR1 = 0;
	p_LCDRegs->LCCR2 = 0;
	p_LCDRegs->LCCR3 = 0;
	p_LCDRegs->LCCR4 = 0;
	p_LCDRegs->LCCR5 = (LCD_SOFM1|LCD_SOFM2|LCD_SOFM3|LCD_SOFM4|LCD_SOFM5|LCD_SOFM6|
						LCD_EOFM1|LCD_EOFM2|LCD_EOFM3|LCD_EOFM4|LCD_EOFM5|LCD_EOFM6|
						LCD_BSM1 |LCD_BSM2 |LCD_BSM3 |LCD_BSM4 |LCD_BSM5 |LCD_BSM6 |
						LCD_IUM1 |LCD_IUM2 |LCD_IUM3 |LCD_IUM4 |LCD_IUM5 |LCD_IUM6 );


	// Determine the frame buffer size for the DMA transfer length.
	// Scale the size based on the bpp of the frame buffer to determine
	// an actual size in bytes
	pXllpLCD->FrameBufferSize = pXllpLCD->FrameBufferWidth * pXllpLCD->FrameBufferHeight;
	switch (pXllpLCD->BPP)
	{
		case BPP_1:
			pXllpLCD->FrameBufferSize >>= 3;
			pXllpLCD->PaletteSize = 8;
			break;
		case BPP_2:
			pXllpLCD->FrameBufferSize >>= 2;
			pXllpLCD->PaletteSize = 8;
			break;
		case BPP_4:
			pXllpLCD->FrameBufferSize >>= 1;
			pXllpLCD->PaletteSize = 32;
			break;
		case BPP_8:
			pXllpLCD->PaletteSize = 512;
			break;
		case BPP_16:
			pXllpLCD->FrameBufferSize <<= 1;
			break;
		case BPP_18:		/* Fall through */
		case BPP_18_PACKED:
		case BPP_19:
		case BPP_19_PACKED:
		case BPP_24:
		case BPP_25:
			pXllpLCD->FrameBufferSize <<= 2;
			break;
		default:
			break;
	}

	// Enable the LCD and SRAM clocks
//	XllpLock(XLLP_RESOURCE_CKEN);
	p_CLKRegs->cken = (p_CLKRegs->cken & XLLP_CLKEN_MASK) | CLK_LCD | CLK_SRAM;
//	XllpUnlock(XLLP_RESOURCE_CKEN);

	// Configure the general purpose frame descriptors
	// Set the physical address of the frame descriptor
	pXllpLCD->frameDescriptorCh0fd1->FDADR = LCD_FDADR(pXllpLCD->_DMA_CHANNEL_0_FRAME_DESCRIPTOR_BASE_PHYSICAL);

	// Set the physical address of the frame buffer
	pXllpLCD->frameDescriptorCh0fd1->FSADR = LCD_FSADR(pXllpLCD->_FRAME_BUFFER_BASE_PHYSICAL + pXllpLCD->CurrentPage*pXllpLCD->FrameBufferSize);

	// Clear the frame ID
	pXllpLCD->frameDescriptorCh0fd1->FIDR  = LCD_FIDR(0);

	// Set the DMA transfer length to the size of the frame buffer
	pXllpLCD->frameDescriptorCh0fd1->LDCMD = LCD_Len(pXllpLCD->FrameBufferSize);

	// Store the physical address of this frame descriptor in the frame descriptor
	pXllpLCD->frameDescriptorCh0fd1->PHYSADDR = pXllpLCD->frameDescriptorCh0fd1->FDADR;

	// frameDescriptorCh0fd2 is used only if a palette load is performed.
	// Set the physical address of the frame descriptor
	pXllpLCD->frameDescriptorCh0fd2->FDADR = LCD_FDADR(pXllpLCD->_DMA_CHANNEL_0_ALT_FRAME_DESCRIPTOR_BASE_PHYSICAL);

	// Set the physical address of the frame buffer
	pXllpLCD->frameDescriptorCh0fd2->FSADR = LCD_FSADR(pXllpLCD->_FRAME_BUFFER_BASE_PHYSICAL + pXllpLCD->CurrentPage*pXllpLCD->FrameBufferSize);

	// Clear the frame ID
	pXllpLCD->frameDescriptorCh0fd2->FIDR  = LCD_FIDR(0);

	// Set the DMA transfer length to the size of the frame buffer
	pXllpLCD->frameDescriptorCh0fd2->LDCMD = LCD_Len(pXllpLCD->FrameBufferSize);
	
	// Store the physical address of this frame descriptor in the frame descriptor
	pXllpLCD->frameDescriptorCh0fd2->PHYSADDR = pXllpLCD->frameDescriptorCh0fd2->FDADR;
	
	// FBR0 is cleared and is not used.
	p_LCDRegs->FBR0 = 0;

	// Load the contents of FDADR0 with the physical address of this frame descriptor
	p_LCDRegs->FDADR0 = LCD_FDADR(pXllpLCD->frameDescriptorCh0fd1->FDADR);
			
	// Determine the LCLK frequency programmed into the CCCR.
	// This value will be used to calculate a Pixel Clock Divisor (PCD)
	// for a given display type.
	CCCR_L = (p_CLKRegs->cccr & 0x0000001F);


	if (CCCR_L < 8) // L = [2 - 7]

⌨️ 快捷键说明

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