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

📄 lh7a404_clcdc_driver.c.bak

📁 sharp触摸屏测试代码
💻 BAK
📖 第 1 页 / 共 2 页
字号:
/***********************************************************************
 * $Workfile:   LH7A404_clcdc_driver.c  $
 * $Revision:   1.2  $
 * $Author:   WellsK  $
 * $Date:   Mar 29 2004 14:54:20  $
 *
 * Project: LH7A404 CLCDC driver
 *
 * Description:
 *     This file contains driver support for the CLCDC module on the
 *     LH7A404
 *
 *      Revision History:
 * $Log:   //smaicnt2/pvcs/VM/sharpmcu/archives/sharpmcu/software/csps/lh7a404/source/LH7A404_clcdc_driver.c-arc  $
 * 
 *    Rev 1.2   Mar 29 2004 14:54:20   WellsK
 * Added LCD_PICK_INT and LCD_CLEAR_INT ioctl functions.
 * 
 *    Rev 1.1   Oct 28 2003 10:50:02   WellsK
 * Lots of tweaks to support common LCD paramters files in the
 * ABL package. Added color depth configuration ioctl command.
 * 
 *    Rev 1.0   Jun 30 2003 17:12:22   WellsK
 * Initial revision.
 * 
 *
 ***********************************************************************
 * SHARP MICROELECTRONICS OF THE AMERICAS MAKES NO REPRESENTATION
 * OR WARRANTIES WITH RESPECT TO THE PERFORMANCE OF THIS SOFTWARE,
 * AND SPECIFICALLY DISCLAIMS ANY RESPONSIBILITY FOR ANY DAMAGES, 
 * SPECIAL OR CONSEQUENTIAL, CONNECTED WITH THE USE OF THIS SOFTWARE.
 *
 * SHARP MICROELECTRONICS OF THE AMERICAS PROVIDES THIS SOFTWARE SOLELY 
 * FOR THE PURPOSE OF SOFTWARE DEVELOPMENT INCORPORATING THE USE OF A 
 * SHARP MICROCONTROLLER OR SYSTEM-ON-CHIP PRODUCT. USE OF THIS SOURCE
 * FILE IMPLIES ACCEPTANCE OF THESE CONDITIONS.
 *
 * COPYRIGHT (C) 2001 SHARP MICROELECTRONICS OF THE AMERICAS, INC.
 *     CAMAS, WA
 **********************************************************************/

#include "lh7a404_clcdc_driver.h"
#include "lh7a404_csc_driver.h"

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

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

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

/* Array that converts an LCD_INTERRUPT_T to a VCOMP interrupt
   selection bitfield for the CLCDC control word */
STATIC const UNS_32 lcd_vcmp_sel[FRONT_PORCH_START + 1] =
{
    CLCDC_LCDCTRL_VCOMP_VS,
    CLCDC_LCDCTRL_VCOMP_BP,
    CLCDC_LCDCTRL_VCOMP_AV,
    CLCDC_LCDCTRL_VCOMP_FP
};

/***********************************************************************
 * CLCDC driver private functions
 **********************************************************************/

/***********************************************************************
 *
 * Function: lcd_update_clock
 *
 * Purpose: Update the pixel clock
 *
 * Processing:
 *     The closest pixel divider to generate the desired clock frequency
 *     from the AHB clock frequency is computed with a call to
 *     csc_compute_divider. The value of the LCD timing 2 register is
 *     then loaded. If the divider is '1', the 'BCD' divider bit in the
 *     loaded timing 2 word is or'ed into the word. If the divider is 2
 *     or greater, the previous BCD bit and divider value are masked out
 *     of the loaded word and the new divider added into the word. The
 *     changed word is then put back into the LCD timing 2 register.
 *
 * Parameters:
 *     desired_clock : New desired pixel clock frequency in Hz
 *
 * Outputs: None
 *
 * Returns: Nothing
 *
 * Notes: None
 *
 **********************************************************************/
STATIC void lcd_update_clock(CLCDC_CFG_T *lcdcfgptr,
                             UNS_32 desired_clock)
{
    INT_32 pixel_div;
    UNS_32 tmp;
    CLCDC_REGS_T *lcdptr = lcdcfgptr->regptr;

    lcdptr->lcdtiming2|=CLCDC_LCDTIMING2_CLKSEL;
    /* Check which clock is being used */
    if ((lcdptr->lcdtiming2 & CLCDC_LCDTIMING2_CLKSEL) != 0)
    {
        /* Main oscillator is used as clock base */
        pixel_div = csc_compute_divider(CLOCK_MAINOSC,desired_clock);
    }
    else
    {
        pixel_div = csc_compute_divider(csc_get_clock(AHBCLK), desired_clock);
    }



    tmp = lcdptr->lcdtiming2;
    if (pixel_div <= 1)
    {
        /* Pixel clock divider is 1, skip divider logic */
        tmp |= CLCDC_LCDTIMING2_BCD;
    }
    else
    {
        /* Mask off old divider and bypass bits */
        tmp &= ~(CLCDC_LCDTIMING2_BCD | CLCDC_LCDTIMING2_PCD(0x1F));

        /* Use divider logic */
        tmp |= CLCDC_LCDTIMING2_PCD(pixel_div);
    }

    lcdptr->lcdtiming2 = tmp;
}
/***********************************************************************
 *
 * Function: lcd_initialize
 *
 * Purpose: Initialize the LCD controller
 *
 * Processing:
 *     Prior to resetting LCD values, disable the LCD controller. Based
 *     on the values in the passed LCD_PARAM_T structure, generate
 *     the appropriate LCD configuration words and place them in the
 *     correct LCD registers.
 *
 * Parameters:
 *     lcdcfgptr : A pointer to an LCD configuration data structure
 *
 * Outputs: None
 *
 * Returns: TRUE if the LCD was initialized, otherwise FALSE
 *
 * Notes: None
 *
 **********************************************************************/
STATIC BOOL_32 lcd_initialize(CLCDC_CFG_T *lcdcfgptr)
{
    UNS_32 tmp;
    STATUS status = _NO_ERROR;
    CLCDC_REGS_T *lcdptr = lcdcfgptr->regptr;
    LCDICP_REGS_T *icpptr = lcdcfgptr->hrptr;
    LCD_PARAM_T *cgdatptr = lcdcfgptr->dptr;

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

    /* Generate the timing 0 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 timing 1 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 timing 2 word */
    tmp = CLCDC_LCDTIMING2_ACB(cgdatptr->ac_bias_frequency);
    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 (* 8 / 3) */
            tmp = tmp | CLCDC_LCDTIMING2_CPL((
                (cgdatptr->pixels_per_line * 8) / 3) - 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;
    }

    lcdptr->lcdtiming2 = tmp;

    /* Update timing 2 word with correct clock data */
    lcd_update_clock(lcdcfgptr, cgdatptr->optimal_clock);

    /* Skip timing 3 word - just set to 0x0 */
    lcdptr->lcdtiming3 = 0x00000000;

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

    /* Default configuration is 16 bits per pixel with blue and
       green not swapped */
    tmp = (CLCDC_LCDCTRL_BPP16 | CLCDC_LCDCTRL_RGB);

    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_MONO8 | 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;

    /* Additional ADTFT and HRTFT setup */
    if ((cgdatptr->lcd_panel_type == HRTFT) ||
        (cgdatptr->lcd_panel_type == ADTFT))
    {
        /* Setup HR-TFT controller 'setup' register */
        tmp = LCDICP_SETUP_PPL(cgdatptr->pixels_per_line) |
            LCDICP_SETUP_MODE_HRTFT | LCDICP_SETUP_RESERVED |
            LCDICP_SETUP_EN;
        icpptr->lcdicp_setup = tmp;

        /* Setup HR-TFT controller 'control' register */
        tmp = 0x00000000;
        if (cgdatptr->hrtft_cls_enable != 0)
        {
            tmp |= LCDICP_CONTROL_CLSEN;
        }
        if (cgdatptr->hrtft_sps_enable != 0)
        {
            tmp |= LCDICP_CONTROL_SPSEN;
        }
        icpptr->lcdicp_control = tmp;

        /* Setup HR-TFT timing 1 register */
        tmp = (LCDICP_TIMING1_LPDEL(cgdatptr->hrtft_lp_delay) |
            LCDICP_TIMING1_REVDEL(cgdatptr->hrtft_polarity_delay) |
            LCDICP_TIMING1_PS_CLSDEL(cgdatptr->hrtft_lp_to_ps_delay));
        icpptr->lcdicp_timing1 = tmp;

        /* Setup HR-TFT timing 2 register */
        tmp =
            (LCDICP_TIMING2_PS_CLSDEL2(
            cgdatptr->hrtft_spl_to_cls_delay) |
            LCDICP_TIMING2_SPLVALUE(cgdatptr->hrtft_spl_delay));
        icpptr->lcdicp_timing2 = tmp;
    }
    else
    {
        /* Normal display type, set HRTFT bypass mode */
        tmp = LCDICP_SETUP_MODE_BYPASS;
        icpptr->lcdicp_setup = tmp;
    }

    return status;
}

/***********************************************************************
 * CLCDC driver public functions
 **********************************************************************/

/***********************************************************************
 *
 * Function: lcd_open
 *
 * Purpose: Open the LCD
 *
 * Processing:
 *     If init is not FALSE and the passed ipbase does not point to the
 *     CLCDC register base address, return NULL to the caller.
 *     Otherwise, set init to TRUE, save the LCD peripheral register set
 *     addresses for the LCD controller and HRTFT timing block. Disable
 *     the LCD controller. If arg is not 0, then call the lcd_initialize
 *     function with the address of the LCD configuration structure as
 *     its argument. Return a pointer to the LCD config structure to the
 *     caller.
 *
 * Parameters:
 *     ipbase: LCD descriptor device address
 *     arg   : Not used
 *
 * Outputs: None
 *
 * Returns: The pointer to a LCD config structure or NULL
 *
 * Notes: None
 *
 **********************************************************************/
INT_32 lcd_open(void *ipbase, INT_32 arg)
{
    INT_32 status = 0;

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

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

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

        /* If the passed argument was not NULL, then it was a pointer
           to a LCD device configuration structure that needs to be
           configured */
        if (arg != 0)
        {
            lcd_initialize(&lcdcfg);
        }

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

    return status;
}

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

⌨️ 快捷键说明

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