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

📄 lh7a400_lcd_private.c

📁 sharp的arm920t 7A400的评估板附带光盘Sharp KEVLH7A400 v0.3b Welcome to the SHARP KEV7A400 Evaluation board
💻 C
字号:
/***********************************************************************
 * $Workfile:   LH7A400_lcd_private.c  $
 * $Revision:   1.0  $
 * $Author:   WellsK  $
 * $Date:   Aug 28 2002 13:29:04  $
 *
 * Project: Common LCD driver interface
 *
 * Description:
 *  See the header file for information on this package.
 *
 * Revision History:
 * $Log:   //smaicnt2/pvcs/VM/CHIPS/archives/LH7A400/LCD/Application drivers/LH7A400_lcd_private.c-arc  $
 * 
 *    Rev 1.0   Aug 28 2002 13:29:04   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) 2002 SHARP MICROELECTRONICS OF THE AMERICAS, INC.
 *     CAMAS, WA
***********************************************************************/
 
#include "SMA_lcd_driver.h"
#include "LH7A400_lcd_private.h"
#include "LH7A400_map.h"
#include "LH7A400_CSC_driver.h"
#include "LH7A400_EVB_CPLD_driver.h"

//**********************************************************************
// Private functions
//**********************************************************************

/***********************************************************************
*
* Function: lcd_priv_get_divider
*
* Purpose:
*  Determine a divider value for the LCD clock based on the AHB bus
*  clock. This function is used by the init function to determine the
*  optimal divider value, keeping the pixel clock rate of the panel
*  close to nom_freq.
*  
* Processing:
*	TBD
*
* Parameters:
*	TBD
*
* Outputs:
*   None
*
* Returns:
*   The best divider for the AHB bus frequency.
*
* Notes:
*   This function is private to this module.
*
***********************************************************************/
int lcd_priv_get_divider (UNS_32 nom_freq)
{
    UNS_32 lcd_clock, lcd_diff1, lcd_diff2, ahb_speed;
    UNS_32 div = 1;

    // Get AHB bus speed
    ahb_speed = LH7A400_get_hclk ();
    lcd_clock = ahb_speed / div;

    // Try to get the best divider just under the nominal frequency
    while (lcd_clock > nom_freq)
    {
        div++;
        lcd_clock = ahb_speed / div;
    }

    if (div > 1)
    {
        // Determine if 'div' or 'div - 1' is closer to nominal frequency
        if (lcd_clock > nom_freq)
        {
            lcd_diff1 = lcd_clock - nom_freq;
        }
        else
        {
            lcd_diff1 = nom_freq - lcd_clock;
        }

        lcd_clock = ahb_speed / (div - 1);
        if (lcd_clock > nom_freq)
        {
            lcd_diff2 = lcd_clock - nom_freq;
        }
        else
        {
            lcd_diff2 = nom_freq - lcd_clock;
        }

        // If diff1 is greater than diff2, then 'div + 1' is the
        // closest divider.
        if ((lcd_diff1 > lcd_diff2) && (div > 1))
        {
            div--;
        }
    }

    return div;
}

/***********************************************************************
 *
 * Function: lcd_priv_initialize
 *
 * Purpose:
 *  Initializes the LCD controller for a specific panel type.
 *
 * Processing:
 *  See function.
 *
 * Parameters:
 *  panel_id  : Panel enumeration type
 *  fb_addr   : Frame buffer address
 *
 * Outputs:
 *  None
 *
 * Returns:
 *  Nothing
 *
 * Notes:
 *  None
 *
 **********************************************************************/
void lcd_priv_initialize (void *fb_addr)
{
    CLCDCREGS *lcd_regs_ptr = (CLCDCREGS *) LCD_BASE;
    LCDICPREGS *hrtft_regs_ptr = (LCDICPREGS *) LCDICP_BASE;
    GPIOREGS *gpio_regs_ptr = (GPIOREGS *) GPIO_BASE;

    // Disable the LCD controller
    lcd_regs_ptr->lcdctrl = 0;

    // Before initializing the LCD controller, make sure the signals
    // from the SOC are LCD outputs. The signals, by default, are
    // GPIOs and must be configued for the LCD prior to use.
    gpio_regs_ptr->pinmux = (gpio_regs_ptr->pinmux |
        GPIO_PINMUX_PEOCON | GPIO_PINMUX_PDOCON);

    // Program LCD timing registers 0, 1, 2, 3
    lcd_regs_ptr->lcdtiming0 = panel_data->t0;
    lcd_regs_ptr->lcdtiming1 = panel_data->t1;
    lcd_regs_ptr->lcdtiming2 = panel_data->t2;
    lcd_regs_ptr->lcdtiming3 = panel_data->t3;

    // Program HR-TFT register values
    hrtft_regs_ptr->setup   = panel_data->hr_setup;
    hrtft_regs_ptr->control = panel_data->hr_control;
    hrtft_regs_ptr->timing1 = panel_data->hr_t1;
    hrtft_regs_ptr->timing2 = panel_data->hr_t2;

    // Set the pixel clock rate
    panel_data->uppixclk (panel_data->opt_clk);

    // Set the frame buffer address
    panel_data->setfb (fb_addr);

    // Set control register
    lcd_regs_ptr->lcdctrl = panel_data->control;

    // Disable LCD signals in the CPLD
    panel_data->disenab (0);
}

/***********************************************************************
 *
 * Function: lcd_priv_set_bl
 *
 * Purpose:
 *  Sets the backlight intensity (variable intensity).
 *
 * Processing:
 *  The passed value must be a value between 0 and max_intens. The
 *  value of max_intens may be different for different panel types.
 *  On panel types where max_intens = 1, the value of '1' will simply
 *  turn the backlight on. '0' will always turn the backlight off.
 *
 * Parameters:
 *  intens: Backlight intensity value
 *
 * Outputs:
 *  None
 *
 * Returns:
 *  Nothing
 *
 * Notes:
 *  The DC-DC converter 0 is used by default for backlight intensity
 *  control.
 *
 **********************************************************************/
void lcd_priv_set_bl (UNS_16 intens)
{
    DCDCREGS *dcdregs = (DCDCREGS *) DCDC_BASE;

    if (intens == 0)
    {
        // Disable backlight power
        LH7A400_pld_lcd_backlight_off ();
    }
    else
    {
        // Enable backlight power
        LH7A400_pld_lcd_backlight_on ();

        // Limit value of intens to PWM value
        intens = intens & 0xF;
        intens = intens + (intens << 4);

        dcdregs->pmpfreq = PMPFREQ_DRV0_PREHI (7) |
            PMPFREQ_DRV0_PRELO (7);
        dcdregs->pmpcon = intens;
    }
}

/***********************************************************************
 *
 * Function: lcd_priv_disab_enab
 *
 * Purpose:
 *  Disable or enable the LCD controller.
 *
 * Processing:
 *  See function.
 *
 * Parameters:
 *  None
 *
 * Outputs:
 *  None
 *
 * Returns:
 *  Nothing
 *
 * Notes:
 *  None
 *
 **********************************************************************/
void lcd_priv_disab_enab (UNS_16 off_on)
{
    CLCDCREGS *lcd_regs_ptr = (CLCDCREGS *) LCD_BASE;

    // Turn off LCD panel
    if (off_on == 0)
    {
        // Disable LCD in control register
        lcd_regs_ptr->lcdctrl = lcd_regs_ptr->lcdctrl &
            (0xFFFFFFFF - CLCDC_LCDCTRL_ENABLE);

        // Turn off backlight and LCD enable bits in CPLD register
        LH7A400_pld_lcd_pwr_disable ();
        LH7A400_pld_lcd_output_disable ();
        LH7A400_pld_lcd_display_disable ();
    }
    else
    {
        // Turn on LCD in the CPLD
        LH7A400_pld_lcd_pwr_enable ();
        LH7A400_pld_lcd_output_enable ();
        LH7A400_pld_lcd_display_enable ();

        // Enable LCD in control register
        lcd_regs_ptr->lcdctrl = lcd_regs_ptr->lcdctrl |
           CLCDC_LCDCTRL_ENABLE;
    }
}

/***********************************************************************
 *
 * Function: lcd_set_framebuffer
 *
 * Purpose:
 *  Set or reset the frame buffer location.
 *
 * Processing:
 *  See function.
 *
 * Parameters:
 *  fb_addr : Frame buffer address
 *
 * Outputs:
 *  None
 *
 * Returns:
 *  Nothing
 *
 * Notes:
 *  None
 *
 **********************************************************************/
void lcd_priv_set_fb (void *fb_addr)
{
    CLCDCREGS *lcd_regs_ptr = (CLCDCREGS *) LCD_BASE;

    // Set high and low 16-bits of frame buffer address
    lcd_regs_ptr->lcdupbase = (UNS_32) fb_addr;
}

/***********************************************************************
 *
 * Function: lcd_set_palette
 *
 * Purpose:
 *  Configure the palette.
 *
 * Processing:
 *  See function.
 *
 * Parameters:
 *  fb_addr : Frame buffer address
 *
 * Outputs:
 *  None
 *
 * Returns:
 *  Nothing
 *
 * Notes:
 *  None
 *
 **********************************************************************/
void lcd_priv_set_pal (UNS_16 *palette)
{
    INT_32 i;
    CLCDCREGS *lcd_regs_ptr = (CLCDCREGS *) LCD_BASE;

    // Update palette memory with the passed palette
    for (i = 0; i < 128; i++)
    {
        lcd_regs_ptr->lcdpalette [i] = (palette [i * 2] +
            palette [i * 2 + 1]);
    }
}

/***********************************************************************
 *
 * Function: lcd_priv_update_pixclk
 *
 * Purpose:
 *  Update the pixel clock rate.
 *
 * Processing:
 *  See function.
 *
 * Parameters:
 *  None
 *
 * Outputs:
 *  None
 *
 * Returns:
 *  Nothing
 *
 * Notes:
 *  None
 *
 **********************************************************************/
void lcd_priv_update_pixclk (UNS_32 pixel_clock)
{
    UNS_32 lcd_progval, lcd_div;
    CLCDCREGS *lcd_regs_ptr = (CLCDCREGS *) LCD_BASE;

    // Get required LCD clock divider
    lcd_div = lcd_priv_get_divider (pixel_clock);

    // If LCD divider is '1', then use clock bypass mode
    if (lcd_div == 1)
    {
        // Force bypass of clock divider (divider = 1)
        lcd_progval = CLCDC_LCDTIMING2_BCD;
    }
    else
    {
        // Use panel clock divisor (divider of 2 or greater)
        lcd_progval = CLCDC_LCDTIMING2_PCD (lcd_div);
    }

    // Update bypass and divider fields in timing register 2
    lcd_regs_ptr->lcdtiming2 = (lcd_regs_ptr->lcdtiming2 &
        ~(CLCDC_LCDTIMING2_BCD | 0x1F)) | lcd_progval;
}

⌨️ 快捷键说明

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