📄 lh7a400_clcdc_driver.c
字号:
/**********************************************************************
* $Workfile: LH7A400_CLCDC_driver.c $
* $Revision: 1.6 $
* $Author: MaysR $
* $Date: Aug 14 2002 18:49:08 $
*
* Project: LH7A400
*
* Description:
* LH7A400 Color LCD Controller device driver
*
* Revision History:
* $Log: //smaicnt2/pvcs/VM/CHIPS/archives/LH7A400/LCD/Drivers/LH7A400_CLCDC_driver.c-arc $
*
* Rev 1.6 Aug 14 2002 18:49:08 MaysR
* Corrected power on and off sequence of LCD panels.
* Changed function call names to match new names in CPLD
* driver.
* Made a work around in the init code to test HR-TFT type before
* register is actually set. This still needs to be addressed.
*
* Rev 1.5 Apr 19 2002 14:10:30 SuryanG
* Workaround to enable LCD power for TFT on Rev. B0 silicon.
*
* Rev 1.4 Jan 09 2002 09:22:10 KovitzP
* Added a number of functions. Changed the prefix of function
* calls from clcdc to lcd because function calls use both the
* CLCDC and the LCDICP; together, these IP blocks make up
* the LCD controller system.
*
* Rev 1.3 Jan 07 2002 12:04:52 MaysR
* Modified LCD ON/OFF routines to add CSTN support. This is a
* temporary fix. Need to have a global setting for CSTN displays.
*
* Rev 1.2 Nov 15 2001 15:30:56 SuryanG
* Modified to use mmu_map_virtual_to_physical() instead of hard defined
* addresses.
*
* Rev 1.1 Nov 08 2001 18:14:58 SuryanG
* No code change. Added file banner.
*
* Rev 1.0 Nov 07 2001 19:00:24 SuryanG
* Initial revision.
*
* COPYRIGHT (C) 2001 SHARP MICROELECTRONICS OF THE AMERICAS, INC.
* CAMAS, WA
*********************************************************************/
/* No support for CSTN displays in this revision */
#include "LH7A400_CLCDC_driver.h"
#include "LH7A400_evb.h"
#include "LH7A400_EVB_CPLD_driver.h"
#include "LH7A400_cp15_driver.h"
#include "LH7A400_CSC_driver.h"
#include "LH7A400_evbutil.h"
/**********************************************************************
* Function: lcd_init, lcd_auto_init
*
* Purpose: Call one of these functions first. lcd_init() allows you to
* specify a specific display type. lcd_auto_init() reads the
* display type from the DIP switches on the display board as
* specified in the typedef for display_type_t in
* LH7A400_CLCDC_driver.h.
*
* This function initializes the CLCDC controller on the
* LH7A400 according to the type of display, based on the
* parameters in the lcd_settings[] table.
*
* Processing: This function first tries to compute the divisor value
* that needs to be programmed into the CLCDC controller to
* generate the pixel clock from the current HCLK. If the
* divisor is in the 0 - 31 range, the function proceeds to
* initialize the CLCDC controller registers with the
* settings defined for this particular display.
*
* It also clears the CLCDC palette and enables all the LCD
* control signals.
*
* Parameters (lcd_init only): lcd_type: enumerated type indicating the
* LCD panel connected
*
* Outputs: None
*
* Returns:
* _ERROR if the display board switches do not match the
* display type passed in the argument
* _ERROR if the LCD pixel clock cannot be generated by
* the controller with the current system settings
* _NO_ERROR if the initialization is successful
*
* Notes: Ensure that the DIP switch settings on the display board
* match the type of display mounted on the board.
**********************************************************************/
INT_32 lcd_auto_init(void)
{
display_type_t lcd_type;
lcd_type = lcd_read_display_type();
return lcd_init(lcd_type);
}
INT_32 lcd_init(display_type_t lcd_type)
{
INT_32 pcd_value;
INT_32 hclk;
INT_32 i;
if (lcd_type >= MAX_DISPLAY)
return _ERROR;
/*
make sure display that was previously on is off and that the LCD
control register is initialized with the controller signals off.
*/
lcd_off(lcd_type);
hclk = LH7A400_get_hclk(); /* what frequency do we have? */
/* can we use this hclk to generate a pixel clock? */
pcd_value = (hclk / lcd_settings[lcd_type].typ_clk);
if (pcd_value < 2)
{
/* then hclk is too slow to use pixel clock divider;
see if we can use hclk as the pixel clock */
if (hclk < lcd_settings[lcd_type].min_clk ||
hclk > lcd_settings[lcd_type].max_clk)
return _ERROR;
else
CLCDC->lcdtiming2 = lcd_settings[lcd_type].timing2 |
CLCDC_LCDTIMING2_PCD(0) |
CLCDC_LCDTIMING2_BCD;
}
else if (pcd_value > 31 )
{
/* then can't make pixel clock from hclk.
select base clock and try again */
pcd_value = (LH7A400_BASE_CLOCK / \
lcd_settings[lcd_type].typ_clk) - 1;
if (pcd_value < 0 )
{
if (lcd_settings[lcd_type].typ_clk > LH7A400_BASE_CLOCK ||
lcd_settings[lcd_type].max_clk < LH7A400_BASE_CLOCK)
return _ERROR; // can't set up controller with this clock
}
CLCDC->lcdtiming2 = lcd_settings[lcd_type].timing2 |
CLCDC_LCDTIMING2_PCD(pcd_value) |
CLCDC_LCDTIMING2_CLKSEL;
}
else
{
if(pcd_value < 2)
{
pcd_value = 2;
}
/* can get a good pixel clock from hclk */
CLCDC->lcdtiming2 = lcd_settings[lcd_type].timing2 |
CLCDC_LCDTIMING2_PCD(pcd_value);
}
/* Set up LCD registers */
// if (lcd_display_is_hrtft()) //-rlm can't do this yet..
if (lcd_type == DISP_LQ039Q2DS53)
{
LCDICP->control = lcd_settings[lcd_type].lcdicp_ctrl;
LCDICP->setup = lcd_settings[lcd_type].lcdicp_setup;
LCDICP->timing1 = lcd_settings[lcd_type].lcdicp_timing1;
LCDICP->timing2 = lcd_settings[lcd_type].lcdicp_timing2;
}
CLCDC->lcdtiming0 = lcd_settings[lcd_type].timing0;
CLCDC->lcdtiming1 = lcd_settings[lcd_type].timing1;
CLCDC->lcdtiming3 = lcd_settings[lcd_type].timing3;
CLCDC->lcdintrenable = lcd_settings[lcd_type].intrenable;
/* clear the palette (color is black )*/
for (i = 0;
i < sizeof(CLCDC->lcdpalette) / sizeof(CLCDC->lcdpalette[0]);
i++)
{
CLCDC->lcdpalette[i] = 0;
}
/* set the pin mux to enable all required LCD signals */
GPIO->pinmux |= (GPIO_PINMUX_PEOCON | GPIO_PINMUX_PDOCON);
if (!lcd_display_is_hrtft())
GPIO->pcdr = 0x4;
return _NO_ERROR;
}
/**********************************************************************
* Function: lcd_draw
*
* Purpose: This is the function exposed to the applications. It can
* be called anytime after clcdc_init is called. This hides
* the frame buffer and palette implementation from higher
* level functions. It does not support a "device context" or
* an off-screen buffer yet.
*
* Processing: This function decides whether the palette is required
* based on the bits-per-pixels and displays the image
* passed as argument.
*
* Parameters: bitmap - pointer to memory location at which the
* image is stored. This memory location can be either
* internal RAM or SDRAM. If using the MMU, ensure that
* IMAGE_BUFFER_PHYSICAL_BASE is correctly defined and
* that the section of memory holding the image is
* uncached.
* bpp - number of bits-per-pixel
* palette - pointer to color palette of the image.
* Should be NULL if bits-per-pixel is higher than 8.
*
* Outputs: None
*
* Returns: _ERROR if there is no palette associated with 1, 2, 4 or
* 8 bits-per-pixel displays, else _NO_ERROR.
**********************************************************************/
INT_32 lcd_draw(void *bitmap, UNS_32 bpp, UNS_32 *palette)
{
/* we don't need a color palette for bitmaps having 16 bits per
pixel or higher */
if (bpp < 16)
{
if (NULL == palette)
{
return _ERROR;
}
lcd_load_palette((void *)palette, _SBF(bpp, 1));
}
lcd_set_bits_per_pixel(bpp);
lcd_display_frame_buffer(bitmap);
return _NO_ERROR;
}
/**********************************************************************
* Function: lcd_on
*
* Purpose: Switches on all the LCD control signals
*
* Processing: Switches on the LCD power, enable and backlight
*
* Parameters: lcd_type - enumerated type display indicating the type
* of display connected.
*
* Outputs: None
*
* Returns: None
***********************************************************************/
void lcd_on(display_type_t lcd_type)
{
/* start the control signals */
CLCDC->lcdctrl = lcd_settings[lcd_type].ctrl | CLCDC_LCDCTRL_PWR;
if (lcd_display_is_stn() && !lcd_display_is_mono())
{
LH7A400_pld_cstn_power_on();
}
else // if HRTFT ??
{
LH7A400_pld_lcd_pwr_enable();
LH7A400_delay_timer_msecs(1);
}
LH7A400_pld_lcd_display_enable();
LH7A400_pld_lcd_output_enable();
LH7A400_pld_lcd_backlight_on();
}
/**********************************************************************
* Function: lcd_off
*
* Purpose: Switches off all the LCD control signals
*
* Processing: Switches off the LCD power, enable and backlight
*
* Parameters: lcd_type - enumerated type display indicating the type
* of display connected.
*
* Outputs: None
*
* Returns: None
**********************************************************************/
void lcd_off(display_type_t lcd_type)
{
LH7A400_pld_lcd_backlight_off();
LH7A400_pld_lcd_output_disable();
LH7A400_pld_lcd_display_disable();
if (lcd_display_is_stn() && !lcd_display_is_mono() )
{
LH7A400_pld_cstn_power_off();
}
else // if HRTFT ??
{
LH7A400_delay_timer_msecs(1);
LH7A400_pld_lcd_pwr_disable();
}
CLCDC->lcdctrl = lcd_settings[lcd_type].ctrl;
}
/**********************************************************************
* Function: lcd_display_frame_buffer
*
* Purpose: Local function to set up the LCD controller DMA base
* address to actually display the frame buffer.
*
* Processing: Checks if the image is in the internal RAM. If not,
* adds the physical address offset and loads the LCD
* DMA base register with this address. If the image is
* in internal RAM, directly loads the address to the
* LCD DMA register.
*
* Parameters: frame_buffer - Pointer to image location. Must satisfy
* constraints detailed in the CLCDC Controller section
* of the LH7A400 Programmers Manual
*
* Outputs: None
*
* Returns: None
***********************************************************************/
void lcd_display_frame_buffer(void *frame_buffer)
{
register UNS_32 addr;
if( (UNS_32) frame_buffer >= 0xB0000000 &&
(UNS_32) frame_buffer <= 0xB0014000 )
{
addr = (UNS_32)frame_buffer;
}
else
{
addr = LH7A400_cp15_map_virtual_to_physical((void *)frame_buffer);
}
CLCDC->lcdupbase = addr;
}
/**********************************************************************
* Function: lcd_load_palette
*
* Purpose: Sets up the CLCDC color palette
*
* Processing: This function supports loading of the color palette
* from the C file generated by the bmp2c utility. It
* expects the palette to be passed as an array of 32-bit
* BGR entries having the following format:
* 7:3 - Blue
* 2:0 - Not used
* 15:11 - Green
* 10:8 - Not used
* 23:19 - Red
* 18:16 - Not used
* 31:24 - Not used
*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -