📄 lcd_driver.c
字号:
/***********************************************************************
* 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 "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)
{
PINSEL10_bit.GPIO_TRACE = 0x0; /* disable ETM interface */
PINSEL2_bit.P1_2 = 0x2; /* enable MCICLK */
PINSEL3_bit.P1_20 = 0x1; /* enable LCD6_LCD10 */
PINSEL3_bit.P1_21 = 0x1; /* enable LCD7_LCD11 */
PINSEL3_bit.P1_22 = 0x1; /* enable LCD8_LCD12 */
PINSEL3_bit.P1_23 = 0x1; /* enable LCD9_LCD13 */
PINSEL3_bit.P1_24 = 0x1; /* enable LCD10_LCD14 */
PINSEL3_bit.P1_25 = 0x1; /* enable LCD11_LCD15 */
PINSEL3_bit.P1_26 = 0x1; /* enable LCD12_LCD20 */
PINSEL3_bit.P1_27 = 0x1; /* enable LCD13_LCD21 */
PINSEL3_bit.P1_28 = 0x1; /* enable LCD14_LCD22 */
PINSEL3_bit.P1_29 = 0x1; /* enable LCD15_LCD23 */
PINSEL4_bit.P2_0 = 0x3; /* enable LCDPWR */
PINSEL4_bit.P2_1 = 0x3; /* enable LCDLE */
PINSEL4_bit.P2_2 = 0x3; /* enable LCDCP */
PINSEL4_bit.P2_3 = 0x3; /* enable LCDFP */
PINSEL4_bit.P2_4 = 0x3; /* enable LCDAC */
PINSEL4_bit.P2_5 = 0x3; /* enable LCDLP */
PINSEL4_bit.P2_6 = 0x3; /* enable LCD0_LCD4 */
PINSEL4_bit.P2_7 = 0x3; /* enable LCD1_LCD5 */
PINSEL4_bit.P2_8 = 0x3; /* enable LCD2_LCD6 */
PINSEL4_bit.P2_9 = 0x3; /* enable LCD3_LCD7 */
PINSEL4_bit.P2_12 = 0x1; /* enable LCD4_LCD3_LCD8_LCD18 */
PINSEL4_bit.P2_13 = 0x1; /* enable LCD5_LCD9_LCD19 */
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);
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,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -