📄 xllp_lcd.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
#include "xllp_defs.h"
#include "xllp_serialization.h"
#include "xllp_lcd.h"
#include "xllp_gpio.h"
#include "xllp_ost.h"
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;
// 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 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:
// suspend if LCD is enabled
if (p_LCDRegs->LCCR0 & LCD_ENB)
{
// 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; // GPIO16
p_GPIORegs->GPCR2 |= XLLP_BIT_17; // GPIO81 = #PSAVE
}
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 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;
XLLP_UINT32_T LockID;
XLLP_UINT32_T LockID2;
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
LockID = XllpLock(CKEN);
p_CLKRegs->cken = (p_CLKRegs->cken & XLLP_CLKEN_MASK) | CLK_LCD | CLK_SRAM;
XllpUnlock(LockID);
// 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]
LCLK = (13 * CCCR_L) * 100;
else if (CCCR_L < 17) // L = [8 - 16]
LCLK = ((13 * CCCR_L) * 100) >> 1;
else if (CCCR_L < 32) // L = [17 - 31]
LCLK = ((13 * CCCR_L) * 100) >> 2;
// Convert the bpp setting into a value that the LCD controller understands.
switch(pXllpLCD->BPP)
{
case BPP_1:
BPP = 0;
break;
case BPP_2:
BPP = 1;
break;
case BPP_4:
BPP = 2;
break;
case BPP_8:
BPP = 3;
break;
case BPP_16:
BPP = 4;
break;
case BPP_18:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -