常州市润邦电子科技有限公司

热保护器测试专业供应商

 

PXA270下 LCD驱动

 

一、硬件

1 LCD的分类

       主要分2类,主动式的TFT LCD和被动式的STN DSTN。当然它们的制造原理是不同的,但对我们应用工程师来说,最大的区别就是驱动时钟不同。TFT的时钟一直有,数据通讯是通过使能芯片的方式进行的。STNDSTN的时钟只有在数据通讯的时候才有。

2 我们的系统同时支持TFTSTNDSTN,硬件上面使用了模拟开关。

其它PCLK,LCLK,VCLK等的接线方式一样。

 

二、软件

       1 Eboot下的驱动

              原来的Eboot不支持LCD,我们将PXA270_LCD目录下的dispdrvr.c移植到eboot下。由于此驱动是为WinCE操作系统写的,在Eboot下要做较大的调整

1.1    原来LCD的配置信息在注册表里,Eboot下没有注册表,我们把有关信息保存在 Flash中,修改如下:

BOOL ReadRegistryData()

{

    LONG regError;

    HKEY hKey;

    DWORD dwDataSize;

    TCHAR DisplayType[64];

 

v_pCFG = (PEBOOT_CFG)VirtualAllocCopyPhysical(sizeof(EBOOT_CFG),"DispDrvrInitialize : v_pCFG",(PVOID)(XSBASE270_G_BASE_PA_BOOT_FLASH+IMAGE_BOOT_CONFIG_FLASH_OFFSET));

RETAILMSG(1, (TEXT("Type:%d"r"n"),v_pCFG->dwDisplayType));

nDisplayType=v_pCFG->dwDisplayType;

switch(nDisplayType)

{

        case NANYALM702:

               DispDrvr_cxScreen=640;

               DispDrvr_cyScreen=480;

               bpp=8;

               break;

        case AU104:

               DispDrvr_cxScreen=800;

               DispDrvr_cyScreen=600;

               bpp=16;

               break;

        default:

        case VLFSDD320240:

               DispDrvr_cxScreen=320;

               DispDrvr_cyScreen=240;

               bpp=8;

               break;    

 

}

 

    // bDoRotation is used to indicate whether or not a rotation of the frame buffer

    // is required in order to orient it correctly for the target display.

    bDoRotation = FALSE;

    switch (nDisplayType)

    {

    case LTM04C380K:    // native landscape 640x480

    case LM8V31:        // native landscape 640x480

    case VLFSDD320240: // native landscape 320x240

case NANYALM702:    // native landscape 640x480

        if (DispDrvr_cxScreen < DispDrvr_cyScreen)

        {

            bDoRotation = TRUE;

        }

        break;

 

    case LQ64D341:        // native portrait, 176x220

    case LTM035A776C:    // native portrait, 240x320

        if (DispDrvr_cxScreen > DispDrvr_cyScreen)

        {

            bDoRotation = TRUE;

        }

        break;

 

    default:

        break;

    }

 

    // Calculate the stride of the frame buffer

    DispDrvr_cdwStride = DispDrvr_cxScreen * bpp / 8;

 

    return (TRUE);

}

1.2    指定LCD Buffer,配置LCD控制寄存器

BOOL MapVirtualAddress()

{

 

g_DisplayBaseVirtual =(DWORD)OALPAtoVA(0xA3A80000, FALSE);

g_DisplayBasePhysical=(DWORD)(0xA3A80000);

 

    v_pDMAC = (P_XLLP_DMAC_T)OALPAtoVA(BULVERDE_BASE_REG_PA_DMAC, FALSE);

    if (!v_pDMAC)

    {

        Cleanup();

        return FALSE;

    }

 

    v_pI2C = (volatile unsigned int *)OALPAtoVA(BULVERDE_BASE_REG_PA_I2C, FALSE);

    if (!v_pI2C)

    {

        Cleanup();

        return FALSE;

    }

 

    v_pOSTRegs = (volatile unsigned int *)OALPAtoVA(BULVERDE_BASE_REG_PA_OST, FALSE);

    if (!v_pOSTRegs)

    {

        Cleanup();

        return FALSE;

    }

 

    v_pLcdRegs = (volatile LCDRegs *)OALPAtoVA(BULVERDE_BASE_REG_PA_LCD, FALSE);

    if (!v_pLcdRegs)

    {

        Cleanup();

        return FALSE;

    }

 

    v_pClkRegs = (volatile XLLP_CLKMGR_T *)OALPAtoVA(BULVERDE_BASE_REG_PA_CLKMGR, FALSE);

    if (!v_pClkRegs)

    {

        Cleanup();

        return FALSE;

    }

   

    v_pGPIORegs = (volatile XLLP_GPIO_T *)OALPAtoVA(BULVERDE_BASE_REG_PA_GPIO, FALSE);

    if (!v_pGPIORegs)

    {

        Cleanup();

        return FALSE;

    }

 

    v_pCPLDRegs = (volatile XSBASE270_G_CPLD_REGS *)OALPAtoVA(XSBASE270_G_BASE_REG_PA_CPLD, FALSE);

    if (!v_pCPLDRegs)

    {

        Cleanup();

        return FALSE;

    }

   

    frameDescriptorCh0fd1 = (volatile LCD_FRAME_DESCRIPTOR *)(DMA_CHANNEL_0_FRAME_DESCRIPTOR_BASE_VIRTUAL);

frameDescriptorCh0fd2 = (volatile LCD_FRAME_DESCRIPTOR *)(DMA_CHANNEL_0_ALT_FRAME_DESCRIPTOR_BASE_VIRTUAL);

    frameDescriptorCh1     = (volatile LCD_FRAME_DESCRIPTOR *)(DMA_CHANNEL_1_FRAME_DESCRIPTOR_BASE_VIRTUAL);

    frameDescriptorPalette = (volatile LCD_FRAME_DESCRIPTOR *)(PALETTE_FRAME_DESCRIPTOR_BASE_VIRTUAL);

    v_pPaletteBuffer       = (volatile LCD_PALETTE *)(PALETTE_BUFFER_BASE_VIRTUAL);

 

gFrameBuffer =(PBYTE)FRAME_BUFFER_0_BASE_VIRTUAL;// (PBYTE)OALPAtoVA(FRAME_BUFFER_0_BASE_PHYSICAL, FALSE);

 

    if (!gFrameBuffer)

    {

        Cleanup();

        return FALSE;

    }   

 

 

 

  

 

    return TRUE;

}

1.3    加入LCD 测试代码

void lcd_test()

{

    DWORD i,j;

    int color = 0;

    unsigned int DispDrvr_cxScreen,DispDrvr_cyScreen;

//    DWORD rmask=0xF800F800, gmask=0x07E007E0, bmask = 0x001F001F;

//    DWORD rmask=0x88888888, gmask=0x66666666, bmask = 0x33333333;

DWORD bmask[] ={0x00000000,0x00010001,0x00030003,0x00070007,0x000F000F,0x001F001F};

    BYTE r = 0x7F, g = 0x7F , b = 0x7F;

UINT32 CurrTime,PreTime=0;

    unsigned * fbp = (unsigned *)gFrameBuffer + (activeFrameBuffer * frameBufferSize);

    DisplayLightConvert((unsigned char)(g_EbootCFG.dwContrast)*(255/9));

//    EdbgOutputDebugString("DispDrvr_cxScreen=%d,DispDrvr_cyScreen=%d"r"n",DispDrvr_cxScreen,DispDrvr_cyScreen);

//      for(j=0;j<10;j++)

//      {

//             CurrTime = OEMEthGetSecs();

//             if(CurrTime>PreTime+2)

//             {

//                    PreTime=CurrTime;

//                    color++;

//                    if(color>1)

//                           color=0;

//                    r=0;

//                    g=0;

//                    b=0;

//                    fbp = (unsigned *)gFrameBuffer + (activeFrameBuffer * frameBufferSize);

//                    EdbgOutputDebugString("fbp=%d"n",fbp);

//             }

//             else

//                    continue;

//             for(i=0;i<15;i++)

//             {

//                    DisplayOneChar(F8X14DotsTbl['A'+i],0,i);

//             }    

//     

//             DisplayString("Welcome to RTPO MTCN",10,7);

//      }

fbp = (unsigned *)gFrameBuffer + (activeFrameBuffer * frameBufferSize);

DisplayLogo(fbp,GetDisplayType());

GetDispalyXY(&DispDrvr_cxScreen,&DispDrvr_cyScreen);

 

if(DispDrvr_cxScreen>MAX_BMP_WIDTH)

        return;

if(DispDrvr_cyScreen>MAX_BMP_HEIGHT)

        return;

DisplayVersion();

fbp = (unsigned *)gFrameBuffer + (activeFrameBuffer * frameBufferSize);

    ProgressBar_Init(fbp,DispDrvr_cxScreen/6,DispDrvr_cyScreen*3/4,DispDrvr_cxScreen*4/6,DispDrvr_cxScreen/12,DispDrvr_cxScreen);

}

 

 

2          WinCELCD的修改

2.1    LCD的配置信息原来从注册表,现在从Flash中读取

这和eboot一样,修改BOOL ReadRegistryData()函数。

 

2.2    加入对黑白灰度屏的支持

void DispDrvrSetPalette (const PALETTEENTRY source[],unsigned short firstEntry,unsigned short numEntries)

{

    int i;

    int end = firstEntry + numEntries;

 

#if 0

    // Don't walk off the end of the palette buffer.

    if (firstEntry > sizeof(source) || end >= sizeof(source))

    {

        return;

    }

#endif     

 

    EnterCriticalSection(&frameDescriptorMutex);

 

RETAILMSG(1,(TEXT("DispDrvrSetPalette: firstEntry=%d, numEntries=%d"r"n"), firstEntry, numEntries));

 

 

if( (VLFSDD320240 == XllpLCD.DisplayType || NANYALM702 == XllpLCD.DisplayType) && 256 == numEntries)

{

        // store 256 gray-scale palette data

        // Y = 0.3*R + 0.59*G + 0.11*B

        for(i = 0; i < 256; i++)

        { 

               v_pPaletteBuffer->palette[i] = (30 * source[i].peRed + 59 * source[i].peGreen + 11 * source[i].peBlue) / 100;

        }

        v_pPaletteBuffer->palette[0] = 0;

}

else

{

        // Store the palette entries into palette ram

        for(i=firstEntry;i<end;i++)

        {

        // store 5 bits red, 6 bits green, and 5 bits blue

        v_pPaletteBuffer->palette[i] = (

            (source[i].peBlue)            >> 3    |

            ((source[i].peGreen & 0xfc)    << 3)    |

            ((source[i].peRed    & 0xf8)    << 8)

            );

        }

}

 

    XllpLCDLoadPalette(&XllpLCD);

   

    LeaveCriticalSection(&frameDescriptorMutex);

}

2.3    增加显示屏的类型

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:

               BPP = 5;

               break;

        case BPP_18_PACKED:

               BPP = 6;

               break;

        case BPP_19:

               BPP = 7;

               break;

        case BPP_19_PACKED:

               BPP = 8;

               break;

        case BPP_24:

               BPP = 9;

               break;

        case BPP_25:

               BPP = 10;

               break;

        default:

        {

               BPP = 0;

               break;

        }

}

 

switch(pXllpLCD->DisplayType)

{

        case NANYALM702: // 640x480x8 landscape

        {

               //

               // The actual equation requires that we take the ceiling of a floating point result.

               // Rather than use floats, we'll calculate an approximation to the correct PCD value

               // using integers.

               //

               PCD = (LCLK / (2 * NANYALM702_PCLOCK_FREQUENCY));

 

               RETAILMSG(1,(TEXT("NANYA-LM-702: LCLK=%d, L_PCLK=%d KHz, PCD=%d"r"n"), LCLK, NANYALM702_PCLOCK_FREQUENCY*10, PCD));

 

               // Reconfigure the upper panel frame descriptors for dual panel operation by

               // setting the DMA transfer length to half the size of the frame buffer

               pXllpLCD->frameDescriptorCh0fd1->LDCMD = pXllpLCD->FrameBufferSize >> 1;

               pXllpLCD->frameDescriptorCh0fd2->LDCMD = pXllpLCD->FrameBufferSize >> 1;

 

               // Configure the lower panel frame descriptor for dual panel operation.

               // Set the physical address of the frame descriptor

               pXllpLCD->frameDescriptorCh1->FDADR = LCD_FDADR(pXllpLCD->_DMA_CHANNEL_1_FRAME_DESCRIPTOR_BASE_PHYSICAL);

 

               // Set the physical address of the frame buffer

               pXllpLCD->frameDescriptorCh1->FSADR = LCD_FSADR(pXllpLCD->_FRAME_BUFFER_BASE_PHYSICAL + pXllpLCD->CurrentPage*pXllpLCD->FrameBufferSize + (pXllpLCD->FrameBufferSize >> 1));

 

               // Clear the frame ID

               pXllpLCD->frameDescriptorCh1->FIDR = LCD_FIDR(0);

 

               // Set the DMA transfer length to half the size of the frame buffer

               pXllpLCD->frameDescriptorCh1->LDCMD = LCD_Len(pXllpLCD->FrameBufferSize >> 1);

 

               // Store the physical address of this frame descriptor in the frame descriptor

               pXllpLCD->frameDescriptorCh1->PHYSADDR = pXllpLCD->frameDescriptorCh1->FDADR;

              

               // FBR1 is cleared and is not used in this implementation

               p_LCDRegs->FBR1 = 0;

 

               // Load the contents of FDADR1 with the physical address of this frame descriptor

               p_LCDRegs->FDADR1 = pXllpLCD->frameDescriptorCh1->FDADR;

                            

               // Configure the TMED dithering engine

               // Use the magic number described in the EAS, 0x00AA5500;

               p_LCDRegs->TRGBR = LCD_TRS(0x00)   | LCD_TGS(0x55) | LCD_TBS(0xAA);

 

               // Use the magic number described in the EAS, 0x0000754F;

               p_LCDRegs->TCR = LCD_TM2S                    | LCD_TM1S         | LCD_TM2En              | LCD_TM1En        |

                                              LCD_TVBS(0x04)   | LCD_THBS(0x05)| LCD_TSCS(0x03)| 

                                            LCD_TED;

       

               p_LCDRegs->LCCR0 = (LCD_SDS                   | LCD_LDM          | LCD_SFM           | LCD_IUM    |

                                                  LCD_CMS                   |LCD_EFM            | LCD_PDD(0x01) | LCD_BM);

 

               p_LCDRegs->LCCR1 = (LCD_PPL(639)     | LCD_HSW(0x02) |

                                                  LCD_ELW(0x03)   | LCD_BLW(0x03) );

 

               //p_LCDRegs->LCCR2 = (LCD_LPP(479)   | LCD_VSW(0x01) |

               //                                 LCD_EFW(0x00)   | LCD_BFW(0x00) );

               p_LCDRegs->LCCR2 = (LCD_LPP(239) | LCD_VSW(0x01) |          // cqz 2009-2-23 16:35

                                                  LCD_EFW(0x00) | LCD_BFW(0x0) );

 

               p_LCDRegs->LCCR3 = (LCD_PCD(PCD) | LCD_ACB(0xff) |

                                                  LCD_PCP                    | LCD_BPP(BPP) |

                                                  LCD_PDFOR(pXllpLCD->PixelDataFormat));

 

               p_LCDRegs->LCCR4 = LCD_PAL_FOR(0);

               if ( (p_LCDRegs->OVL1C1 & LCD_O1EN) || (p_LCDRegs->OVL2C1 & LCD_O2EN))

               {

                      p_LCDRegs->LCCR4 = LCD_PAL_FOR(1);

               }

        }

        break;

 

        case VLFSDD320240: // 320x240x8 bpp passive monochrome matrix

        {

               //

               // The actual equation requires that we take the ceiling of a floating point result.

               // Rather than use floats, we'll calculate an approximation to the correct PCD value

               // using integers. 

               //

               PCD = (LCLK / (2 * VLFSDD320240_PCLOCK_FREQUENCY));

 

               RETAILMSG(1,(TEXT("VL-FS-DD320240-01: LCLK=%d, L_PCLK=%d KHz, PCD=%d"r"n"), LCLK, VLFSDD320240_PCLOCK_FREQUENCY*10, PCD));

 

               // Configure the TMED dithering engine

               // Use the magic number described in the EAS, 0x00AA5500;

               p_LCDRegs->TRGBR = LCD_TRS(0x00) | LCD_TGS(0x55) | LCD_TBS(0xAA);

 

               // Use the magic number described in the EAS, 0x0000754F;

               p_LCDRegs->TCR = LCD_TM2S | LCD_TM1S | LCD_TM2En | LCD_TM1En             |

                                            LCD_TVBS(0x04) | LCD_THBS(0x05) | LCD_TSCS(0x03)    | 

                                            LCD_TED;

 

               // Configure the LCD Controller Control Registers

               p_LCDRegs->LCCR0 = (LCD_LDM | LCD_SFM | LCD_IUM | LCD_EFM |

                                      LCD_CMS | LCD_QDM | LCD_BM | LCD_OUM );

              

               p_LCDRegs->LCCR1 = (LCD_PPL(0x13F) | LCD_HSW(0x02) |

                                                  LCD_ELW(0x03)   | LCD_BLW(0x3) );    

 

               p_LCDRegs->LCCR2 = (LCD_LPP(0xEF) | LCD_VSW(0x05) |      

                                                  LCD_EFW(0x00) | LCD_BFW(0x0) );

 

               p_LCDRegs->LCCR3 = (LCD_PCD(PCD) | LCD_BPP(BPP) | LCD_ACB(0x10) |

                                      LCD_PCP | LCD_PDFOR(pXllpLCD->PixelDataFormat));

                                   

               p_LCDRegs->LCCR4 = LCD_PAL_FOR(0);

               if ( (p_LCDRegs->OVL1C1 & LCD_O1EN) || (p_LCDRegs->OVL2C1 & LCD_O2EN))

               {

                      p_LCDRegs->LCCR4 = LCD_PAL_FOR(1);

               }    

        }

        break;

       

    case LTM04C380K: // 640x480 16bpp active matrix

        {

 

               //

               // The actual equation requires that we take the ceiling of a floating point result.

               // Rather than use floats, we'll calculate an approximation to the correct PCD value

               // using integers. 

               //

               //PCD = (LCLK / (2 * LTM04C380K_PIXEL_CLOCK_FREQUENCY));

               PCD = 1;        //Modify by Terry for freq

               // Configure the LCD Controller Control Registers

               p_LCDRegs->LCCR0 = (LCD_LDM | LCD_SFM | LCD_IUM | LCD_EFM |

                                                  LCD_PAS | LCD_QDM | LCD_BM | LCD_OUM |

                                                  LCD_RDSTM | LCD_CMDIM | LCD_OUC | LCD_LDDALT);

 

               p_LCDRegs->LCCR1 = (LCD_PPL(0x27FU) | LCD_HSW(0x3f) |

                                                  LCD_ELW(0x21) | LCD_BLW(0x50U) ); //Modufy by Terry@2005-2-5 LCD_BLW(0x9fU)

              

               p_LCDRegs->LCCR2 = (LCD_LPP(0x1df) | LCD_VSW(0x0) |                      //Modufy by Terry@2005-2-23 LCD_VFW(0x02)

                                                  LCD_EFW(0x00) | LCD_BFW(0x20) );    //Modufy by Terry@2005-2-23 LCD_BFW(0x00)

 

               p_LCDRegs->LCCR3 = (LCD_PCD(PCD) | LCD_BPP(BPP) | LCD_PCP |

                                                  LCD_PDFOR(pXllpLCD->PixelDataFormat));

              

               p_LCDRegs->LCCR4 = LCD_PAL_FOR(0);

               if ( (p_LCDRegs->OVL1C1 & LCD_O1EN) || (p_LCDRegs->OVL2C1 & LCD_O2EN))

               {

                      p_LCDRegs->LCCR4 = LCD_PAL_FOR(1);

               }

        }

        break;

 

    case AU104: // 800X600 SVGA TFT

        {//2009-2-26 10:03 Bruce

 

               //

               // The actual equation requires that we take the ceiling of a floating point result.

               // Rather than use floats, we'll calculate an approximation to the correct PCD value

               // using integers. 

               //

               //PCD = (LCLK / (2 * LTM04C380K_PIXEL_CLOCK_FREQUENCY));

               PCD = 1;        //25MHz

               // Configure the LCD Controller Control Registers

               p_LCDRegs->LCCR0 = (LCD_LDM | LCD_SFM | LCD_IUM | LCD_EFM |

                                                  LCD_PAS | LCD_QDM | LCD_BM | LCD_OUM |

                                                  LCD_RDSTM | LCD_CMDIM | LCD_OUC | LCD_LDDALT);

 

               p_LCDRegs->LCCR1 = (LCD_PPL(799) | LCD_HSW(0x04) |

                                                  LCD_ELW(0x17) | LCD_BLW(0x18) );     //Modufy by Terry@2005-2-5 LCD_BLW(0x9fU)

              

               p_LCDRegs->LCCR2 = (LCD_LPP(599) | LCD_VSW(0x02) |                        //Modufy by Terry@2005-2-23 LCD_VFW(0x02)

                                                  LCD_EFW(0x01) | LCD_BFW(0x03) );    //Modufy by Terry@2005-2-23 LCD_BFW(0x00)

 

               p_LCDRegs->LCCR3 = (LCD_PCD(PCD) | LCD_BPP(BPP) | LCD_PCP |

                                                  LCD_PDFOR(pXllpLCD->PixelDataFormat));

              

               p_LCDRegs->LCCR4 = LCD_PAL_FOR(0);

               if ( (p_LCDRegs->OVL1C1 & LCD_O1EN) || (p_LCDRegs->OVL2C1 & LCD_O2EN))

               {

                      p_LCDRegs->LCCR4 = LCD_PAL_FOR(1);

               }

        }

        break;

 

    case LTM035A776C: // 240x320 16bpp active matrix

        {

 

               //

               // The actual equation requires that we take the ceiling of a floating point result.

               // Rather than use floats, we'll calculate an approximation to the correct PCD value

               // using integers.

               //

               PCD = (LCLK / (2 * LTM035A776C_PIXEL_CLOCK_FREQUENCY));

              

               // Configure the LCD Controller Control Registers

               p_LCDRegs->LCCR0 = (LCD_LDM | LCD_SFM | LCD_IUM | LCD_EFM |

                                                  LCD_PAS | LCD_QDM | LCD_BM | LCD_OUM |

                                                  LCD_RDSTM | LCD_CMDIM | LCD_OUC | LCD_LDDALT);

 

               p_LCDRegs->LCCR1 = (LCD_PPL(0xEF) | LCD_HSW(0x04) |

                                                  LCD_ELW(0x04) | LCD_BLW(0x05) );

              

               p_LCDRegs->LCCR2 = (LCD_LPP(0x13f) | LCD_VSW(0x02) |

                                                  LCD_EFW(0x03) | LCD_BFW(0x02) );

 

               p_LCDRegs->LCCR3 = (LCD_PCD(PCD) | LCD_BPP(BPP) | LCD_PCP | LCD_HSP |

                                                  LCD_PDFOR(pXllpLCD->PixelDataFormat));

              

               p_LCDRegs->LCCR4 = LCD_PAL_FOR(0);

               if ( (p_LCDRegs->OVL1C1 & LCD_O1EN) || (p_LCDRegs->OVL2C1 & LCD_O2EN))

               {

                      p_LCDRegs->LCCR4 = LCD_PAL_FOR(1);

              }

        }

        break;

 

    case LM8V31: // 640x480 16bpp dual panel passive

        {

 

               //

               // The actual equation requires that we take the ceiling of a floating point result.

               // Rather than use floats, we'll calculate an approximation to the correct PCD value

               // using integers.

               //

               PCD = (LCLK / (2 * LM8V31_PIXEL_CLOCK_FREQUENCY));

 

               // Reconfigure the upper panel frame descriptors for dual panel operation by

               // setting the DMA transfer length to half the size of the frame buffer

               pXllpLCD->frameDescriptorCh0fd1->LDCMD = pXllpLCD->FrameBufferSize >> 1;

               pXllpLCD->frameDescriptorCh0fd2->LDCMD = pXllpLCD->FrameBufferSize >> 1;

 

               // Configure the lower panel frame descriptor for dual panel operation.

               // Set the physical address of the frame descriptor

               pXllpLCD->frameDescriptorCh1->FDADR = LCD_FDADR(pXllpLCD->_DMA_CHANNEL_1_FRAME_DESCRIPTOR_BASE_PHYSICAL);

 

               // Set the physical address of the frame buffer

               pXllpLCD->frameDescriptorCh1->FSADR = LCD_FSADR(pXllpLCD->_FRAME_BUFFER_BASE_PHYSICAL + pXllpLCD->CurrentPage*pXllpLCD->FrameBufferSize + (pXllpLCD->FrameBufferSize >> 1));

 

               // Clear the frame ID

               pXllpLCD->frameDescriptorCh1->FIDR = LCD_FIDR(0);

 

               // Set the DMA transfer length to half the size of the frame buffer

               pXllpLCD->frameDescriptorCh1->LDCMD = LCD_Len(pXllpLCD->FrameBufferSize >> 1);

 

               // Store the physical address of this frame descriptor in the frame descriptor

               pXllpLCD->frameDescriptorCh1->PHYSADDR = pXllpLCD->frameDescriptorCh1->FDADR;

              

               // FBR1 is cleared and is not used in this implementation

               p_LCDRegs->FBR1 = 0;

 

               // Load the contents of FDADR1 with the physical address of this frame descriptor

               p_LCDRegs->FDADR1 = pXllpLCD->frameDescriptorCh1->FDADR;

       

              

               // Configure the TMED dithering engine

               // Use the magic number described in the EAS, 0x00AA5500;

               p_LCDRegs->TRGBR = LCD_TRS(0x00) | LCD_TGS(0x55) | LCD_TBS(0xAA);

 

               // Use the magic number described in the EAS, 0x0000754F;

               p_LCDRegs->TCR = LCD_TM2S | LCD_TM1S | LCD_TM2En | LCD_TM1En             |

                                            LCD_TVBS(0x04) | LCD_THBS(0x05) | LCD_TSCS(0x03)    | 

                                            LCD_TED;

 

       

               p_LCDRegs->LCCR0 = (LCD_SDS | LCD_LDM | LCD_SFM | LCD_IUM      |

                                                  LCD_EFM | LCD_PDD(0x01)             | LCD_BM      |

                                                  LCD_RDSTM | LCD_CMDIM | LCD_OUC | LCD_LDDALT);

 

              p_LCDRegs->LCCR1 = (LCD_PPL(0x27F) | LCD_HSW(0x02) |

                                                  LCD_ELW(0x03)   | LCD_BLW(0x03) );

 

               p_LCDRegs->LCCR2 = (LCD_LPP(0xef)    | LCD_VSW(0x01) |

                                                  LCD_EFW(0x00)   | LCD_BFW(0x00) );

 

               p_LCDRegs->LCCR3 = (LCD_PCD(PCD) | LCD_ACB(0xff) |

                                                  LCD_PCP                    | LCD_BPP(BPP) |

                                                  LCD_PDFOR(pXllpLCD->PixelDataFormat));

 

               p_LCDRegs->LCCR4 = LCD_PAL_FOR(0);

               if ( (p_LCDRegs->OVL1C1 & LCD_O1EN) || (p_LCDRegs->OVL2C1 & LCD_O2EN))

               {

                      p_LCDRegs->LCCR4 = LCD_PAL_FOR(1);

               }

        }

        break;

    case LQ64D341: // 176x220 active matrix Stinger display

        {

 

               //

               // The actual equation requires that we take the ceiling of a floating point result.

               // Rather than use floats, we'll calculate an approximation to the correct PCD value

               // using integers.

               //

               PCD = (LCLK / (2 * LQ64D341_PIXEL_CLOCK_FREQUENCY));

 

               p_LCDRegs->LCCR0 = ( LCD_LDM | LCD_SFM | LCD_IUM |

                                                   LCD_EFM | LCD_PAS | LCD_BM            |

                                                   LCD_RDSTM | LCD_CMDIM | LCD_OUC | LCD_LDDALT);

 

               p_LCDRegs->LCCR1 = ( LCD_PPL(0xAF) | LCD_HSW(0x02) |

                                                   LCD_ELW(0x7B) | LCD_BLW(0x03) );

 

               p_LCDRegs->LCCR2 = ( LCD_LPP(0xdb) | LCD_VSW(0x01) |

                                                   LCD_EFW(0x02) | LCD_BFW(0x00) );

 

               p_LCDRegs->LCCR3 = ( LCD_PCD(PCD) | LCD_BPP(BPP)   |

                                                   LCD_VSP            | LCD_HSP            | LCD_PCP |

                                                   LCD_OEP           | LCD_PDFOR(pXllpLCD->PixelDataFormat));

 

               p_LCDRegs->LCCR4 = LCD_PAL_FOR(0);

               if ( (p_LCDRegs->OVL1C1 & LCD_O1EN) || (p_LCDRegs->OVL2C1 & LCD_O2EN))

               {

                      p_LCDRegs->LCCR4 = LCD_PAL_FOR(1);

               }

 

        }

        break;

 

case LS022Q8DD06: // Sharp LS022Q8DD06 Sharp 240 x 320 for ZOAR

        {

               //

               // The actual equation requires that we take the ceiling of a floating point result.

               // Rather than use floats, we'll calculate an approximation to the correct PCD value

               // using integers.

               //

 

               PCD = (LCLK / (2 * LS022Q8DD06_PIXEL_CLOCK_FREQUENCY));

 

               // Configure the LCD Controller Control Registers

               p_LCDRegs->LCCR0 = (LCD_LDM | LCD_SFM | LCD_IUM | LCD_EFM |

                                    LCD_PAS | LCD_QDM | LCD_BM | LCD_OUM |

                                    LCD_RDSTM | LCD_CMDIM | LCD_OUC | LCD_LDDALT);

 

               p_LCDRegs->LCCR1 = (LCD_PPL(0xEF) | LCD_HSW(0x01) |

                                    LCD_ELW(0x00) | LCD_BLW(0x07) );

              

               p_LCDRegs->LCCR2 = (LCD_LPP(0x13f) | LCD_VSW(0x02) |

                                    LCD_EFW(0x02) | LCD_BFW(0x00) );

 

               p_LCDRegs->LCCR3 = (LCD_PCD(PCD) | LCD_BPP(BPP) | LCD_PCP |

                                    LCD_PDFOR(pXllpLCD->PixelDataFormat));

              

               p_LCDRegs->LCCR4 = LCD_PAL_FOR(0);

               if ( (p_LCDRegs->OVL1C1 & LCD_O1EN) || (p_LCDRegs->OVL2C1 & LCD_O2EN))

               {

                      p_LCDRegs->LCCR4 = LCD_PAL_FOR(1);

               }

 

               LockID = XllpLock(CKEN);

               p_CLKRegs->cken = (p_CLKRegs->cken & XLLP_CLKEN_MASK) | CLK_SSP3;

               XllpUnlock(LockID);

 

               // Assert chip select on the LCD

               LockID = XllpLock(GPCR2);

               LockID2 = XllpLock(GPSR2);

              

               p_GPIORegs->GPCR2 &= ~XLLP_GPIO_BIT_L_BIAS;

               p_GPIORegs->GPSR2 |= XLLP_GPIO_BIT_L_BIAS;      

              

               XllpOstDelayMilliSeconds(p_OSTRegs, 1);

               p_SSPRegs->sscr0 = 0x00C01030;

               p_SSPRegs->sscr1 = 0x00008000;

               p_SSPRegs->sspsp = 0x0025000C;

               p_SSPRegs->sscr0 |= 0x8F;

 

               // Wait for the operation to complete

               while(p_SSPRegs->sssr & 0x10);

 

               for (i = 0; i < sizeof(LS022Q8DD06_DATA_SET_1) >> 1; i+=2)

               {

                      p_GPIORegs->GPCR2 &= ~XLLP_GPIO_BIT_L_BIAS;

                      p_GPIORegs->GPSR2 |= XLLP_GPIO_BIT_L_BIAS;      

                      p_SSPRegs->ssdr = LS022Q8DD06_DATA_SET_1[i];

                      p_SSPRegs->ssdr = LS022Q8DD06_DATA_SET_1[i+1];

 

                      // Wait for the operation to complete

                      while(p_SSPRegs->sssr & 0x10);

                      XllpOstDelayMicroSeconds(p_OSTRegs, 50);

                      p_GPIORegs->GPSR2 &= ~XLLP_GPIO_BIT_L_BIAS;

                      p_GPIORegs->GPCR2 |= XLLP_GPIO_BIT_L_BIAS;

 

                      XllpOstDelayMilliSeconds(p_OSTRegs, 100);

               }

 

               for (i = 0; i < sizeof(LS022Q8DD06_DATA_SET_2) >> 1; i+=2)

               {

                      p_GPIORegs->GPCR2 &= ~XLLP_GPIO_BIT_L_BIAS;

                      p_GPIORegs->GPSR2 |= XLLP_GPIO_BIT_L_BIAS;      

                      p_SSPRegs->ssdr = LS022Q8DD06_DATA_SET_2[i];

                      p_SSPRegs->ssdr = LS022Q8DD06_DATA_SET_2[i+1];

 

                      // Wait for the operation to complete

                      while(p_SSPRegs->sssr & 0x10);

                      XllpOstDelayMicroSeconds(p_OSTRegs, 50);

                      p_GPIORegs->GPSR2 &= ~XLLP_GPIO_BIT_L_BIAS;

                      p_GPIORegs->GPCR2 |= XLLP_GPIO_BIT_L_BIAS;

              

                      XllpOstDelayMilliSeconds(p_OSTRegs, 100);

               }

 

 

               // De-assert chip select on the LCD

               p_GPIORegs->GPSR2 &= ~XLLP_GPIO_BIT_L_BIAS;

               p_GPIORegs->GPCR2 |= XLLP_GPIO_BIT_L_BIAS;

               XllpUnlock(LockID);

               XllpUnlock(LockID2);

 

        }

        break;

 

default:

        {

 

        }

        break;

}

 

}

2.4     

posted on 2009-07-03 10:41  常州市润邦电子科技  阅读(2375)  评论(1编辑  收藏  举报

导航