📄 lh7a400_lcd_private.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 + -