lcd_driver.c

来自「Keil工程例子,NXP新出的芯片lpc2478的示例代码」· C语言 代码 · 共 703 行 · 第 1/2 页

C
703
字号
/***********************************************************************
 * File:   lcd_driver.c
 * Rev:    1.0
 * Author: Chun Sing Chu
 * Date:   March 26 2007
 *
 * Description:
 *     This file contains driver support for the LCD panel on FCC1 Board
 *
 * Revision History:
 * Rev 1.0 March 26 2007
 * Initial revision.
 * 
 **********************************************************************/

#include "LPC24xx.H"
#include "lcd_params.h"
#include "lcd_driver.h"


/***********************************************************************
 * LCD driver private data and types
 **********************************************************************/

/* LCD device configuration structure type */
typedef struct
{
    BOOL init;          /* Device initialized flag */
    CLCDC_REGS_T *regptr;  /* Pointer to LCD registers */
    LCD_PARAM_T *dptr;     /* Pointer to LCD controller settings */
} CLCDC_CFG_T;

/***********************************************************************
 * Forward declration
 **********************************************************************/
void lcd_configure_gpio(void);


/* LCD device configuration structure */
static CLCDC_CFG_T lcdcfg;

/***********************************************************************
 *
 * Function: lcd_configure_gpio
 *
 * Purpose: Configure the GPIO muxing for LCD based on LCD type
 *
 * Processing:
 *
 * Parameters: 	None
 *
 * Outputs: None
 *
 * Returns: None
 *
 **********************************************************************/
void lcd_configure_gpio(void)
{
   
   PINSEL2|=(1<<5);
   PINSEL2&=~(1<<4);/* enable MCICLK;enable LCD6~LCD15 LCD20~ LCD23*/

   PINSEL3|=(0x55555<<8);
   PINSEL3&=~(0xAAAAA<<8);
   
     PINSEL4|=0xFFF;
    // PINSEL4|=(0x5<<24);
	 PINSEL4|=(0x1<<24);	//add jj
     PINSEL4&=~(0xA<<24);

   PINSEL10&=~(1<<3);  /* disable ETM interface */
   CLCDPINSEL = 0x0000000b;


}


/***********************************************************************
 *
 * Function: lcd_initialize
 *
 * Purpose: Initialize the LCD controller
 *
 * Processing:
 *     Prior to resetting LCD values, disable the LCD controller.
 *     Configurate the LCD registers with the values in the passed 
 *     LCD_PARAM_T structure.
 *
 * Parameters:
 *     lcdcfgptr : A pointer to an LCD configuration data structure
 *
 * Outputs: None
 *
 * Returns: _NO_ERROR if the LCD was initialized, otherwise _ERROR
 *
 **********************************************************************/
BOOL lcd_initialize(CLCDC_CFG_T *lcdcfgptr)
{
    INT32U tmp, i;
    INT32S status = _NO_ERROR;
    CLCDC_REGS_T *lcdptr = lcdcfgptr->regptr;
    LCD_PARAM_T *cgdatptr = lcdcfgptr->dptr;

    /* Disable the display in case it is on */
    lcdptr->lcdctrl &= ~CLCDC_LCDCTRL_ENABLE;

    /* Generate the horizontal axis plane control word */
    tmp = (CLCDC_LCDTIMING0_PPL(cgdatptr->pixels_per_line) |
        CLCDC_LCDTIMING0_HSW(cgdatptr->h_sync_pulse_width) |
        CLCDC_LCDTIMING0_HFP(cgdatptr->h_front_porch) |
        CLCDC_LCDTIMING0_HBP(cgdatptr->h_back_porch));
    lcdptr->lcdtiming0 = tmp;

    /* Generate the vertical axis plane control word */
    tmp = (CLCDC_LCDTIMING1_LPP(cgdatptr->lines_per_panel) |
        CLCDC_LCDTIMING1_VSW(cgdatptr->v_sync_pulse_width) |
        CLCDC_LCDTIMING1_VFP(cgdatptr->v_front_porch) |
        CLCDC_LCDTIMING1_VBP(cgdatptr->v_back_porch));
    lcdptr->lcdtiming1 = tmp;

    /* Generate the clock and signal polarity control word */
    if(cgdatptr->ac_bias_frequency != 0)
    {
	/* STN panel has AC bias value */
    	tmp = CLCDC_LCDTIMING2_ACB(cgdatptr->ac_bias_frequency);
    }
    else
    {
	    tmp = 0;
    }
    if (cgdatptr->invert_output_enable != 0)
    {
        tmp |= CLCDC_LCDTIMING2_IOE;
    }
    if (cgdatptr->invert_panel_clock != 0)
    {
        tmp |= CLCDC_LCDTIMING2_IPC;
    }
    if (cgdatptr->invert_hsync != 0)
    {
        tmp |= CLCDC_LCDTIMING2_IHS;
    }
    if (cgdatptr->invert_vsync != 0)
    {
        tmp |= CLCDC_LCDTIMING2_IVS;
    }

    /* Compute clocks per line based on panel type */
    switch (cgdatptr->lcd_panel_type)
    {
        case MONO_4BIT:
            /* Clocks per line is a quarter of pixels per line */
            tmp = tmp | CLCDC_LCDTIMING2_CPL((cgdatptr->pixels_per_line / 4) - 1);
            break;

        case MONO_8BIT:
            /* Clocks per line is an eighth of pixels per line */
            tmp = tmp | CLCDC_LCDTIMING2_CPL((cgdatptr->pixels_per_line / 8) - 1);
            break;

        case CSTN:
            /* CSTN Clocks per line (* 3 / 8) */
            tmp = tmp | CLCDC_LCDTIMING2_CPL(((cgdatptr->pixels_per_line * 3) / 8) - 1);
            break;
            
        case TFT:
        case ADTFT:
        case HRTFT:
        default:
            /* Clocks per line and pixels per line are the same */
            tmp = tmp | CLCDC_LCDTIMING2_CPL(cgdatptr->pixels_per_line - 1);
            break;
    }

    /* Bypass pixel clock divider */
    tmp = tmp | CLCDC_LCDTIMING2_PCD_LO(12);

    lcdptr->lcdtiming2 = tmp;

    /* Skip line end control word - just set to 0x0 */
    lcdptr->lcdtiming3 = 0x00000000;

    /* Default with all interrupts of */
    lcdptr->lcdimsc = 0x00000000;

    /* Default configuration is 16 bits per pixel with blue and green not swapped */
    tmp = CLCDC_LCDCTRL_BPP16_565_MODE;

    switch (cgdatptr->lcd_panel_type)
    {
        case ADTFT:
        case HRTFT:
        case TFT:
            tmp |= CLCDC_LCDCTRL_TFT;
            break;

        case MONO_4BIT:
            tmp |= CLCDC_LCDCTRL_BW_MONO;
            break;

        case MONO_8BIT:
            tmp |= (CLCDC_LCDCTRL_MON8 | CLCDC_LCDCTRL_BW_MONO);
            break;

        case CSTN:
            ;
            break;

        default:
            /* Unsupported panel type */
            status = _ERROR;
            break;
    }

    /* Dual panel operation */
    if (cgdatptr->dual_panel == 1)
    {
        tmp |= CLCDC_LCDCTRL_DUAL;
    }

    lcdptr->lcdctrl = tmp;

    /* clear the palette (color is black )*/
    for (i = 0; i < sizeof(lcdptr->lcdpalette)/sizeof(lcdptr->lcdpalette[0]); i++)
    {
        lcdptr->lcdpalette[i] = 0xf800;
    }

    /* setup CLCD clock CFG register */
    CLCDCLKCFG = 0x0;

    return status;
}



/***********************************************************************
 *
 * Function: lcd_open
 *
 * Purpose: Open the LCD controller
 *
 * Processing:
 *     If init is not FALSE, return 0x00000000.
 *     Otherwise, return a pointer to the LCD configuration data structure.
 *
 * Parameters:
 *     ipbase: LCD descriptor device address
 *     arg   : LCD type - LCD_PARAM_T
 *
 * Outputs: None
 *
 * Returns: The pointer to a LCD config structure or 0
 *
 **********************************************************************/
INT32S lcd_open(void *lcdbase, INT32S arg)
{
    INT32S status = 0;

    if ((lcdcfg.init == FALSE) && ((CLCDC_REGS_T *) lcdbase == CLCDC))
    {
        /* Device is valid and not previously initialized */
        lcdcfg.init = TRUE;

        /* Save and return address of peripheral block */
        lcdcfg.regptr = (CLCDC_REGS_T *) lcdbase;
        lcdcfg.dptr = (LCD_PARAM_T *) arg;

        /* Disable LCD */
        lcdcfg.regptr->lcdctrl &= ~CLCDC_LCDCTRL_ENABLE;

        /* If the passed argument is not NULL, then it is a pointer
           to a LCD panel parameters structure that needs to be configured */
        if (arg != 0)
        {
            lcd_initialize(&lcdcfg);
			 *(volatile INT32U *)(0xFFE10008) = 0x013F3003; //configuration Optimal clock rate  of lcd add late
            lcd_configure_gpio();
        }

        /* Return pointer to LCD configuration data structure */
        status = (INT32S) &lcdcfg;
    }

    return status;
}

/***********************************************************************
 *
 * Function: lcd_close
 *
 * Purpose: Close the LCD controller
 *
 * Processing:
 *     If init is not TRUE, then return _ERROR to the caller as the
 *     device was not previously opened. Otherwise, disable the LCD,
 *     set init to FALSE, and return _NO_ERROR to the caller.
 *
 * Parameters:
 *     devid: Pointer to LCD config structure
 *
 * Outputs: None
 *
 * Returns: The status of the close operation
 *
 **********************************************************************/
INT32S lcd_close(INT32S devid)
{
	
    CLCDC_CFG_T *lcdcfgptr = (CLCDC_CFG_T *) devid;
    INT32S status = _ERROR;

    if (lcdcfgptr->init == TRUE)
    {
        /* 'Uninitialize' device */
        lcdcfgptr->init = FALSE;
        status = _NO_ERROR;
    }

    return status;
}

/***********************************************************************
 *
 * Function: lcd_ioctl
 *
 * Purpose: LCD configuration block
 *
 * Processing:
 *     This function is a large case block. Based on the passed function
 *     and option values, set or get the appropriate LCD
 *     parameter.
 *
 * Parameters:
 *     devid: Pointer to LCD config structure
 *     cmd:   ioctl command
 *     arg:   ioctl argument
 *
 * Outputs: None
 *
 * Returns: The status of the ioctl operation
 *
 **********************************************************************/
INT32S lcd_ioctl(INT32S devid,
                 INT32S cmd,
                 INT32S arg)
{
    CLCDC_REGS_T *lcd;
    INT32U i;
    CLCDC_CFG_T *lcdcfgptr = (CLCDC_CFG_T *) devid;
    INT32S status = _ERROR;
    

⌨️ 快捷键说明

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