📄 lh79524_clcdc_driver.c
字号:
/***********************************************************************
* $Workfile: lh79524_clcdc_driver.c $
* $Revision: 1.0 $
* $Author: ZhangJ $
* $Date: Oct 20 2004 09:48:54 $
*
* Project: LH79524 CLCDC driver
*
* Description:
* This file contains driver support for the CLCDC module on the
* LH79524
*
* Revision History:
* $Log:: //smaicnt2/pvcs/VM/sharpmcu/archives/sharpmcu/software/csps$
*
* Rev 1.0 Oct 20 2004 09:48:54 ZhangJ
* Initial revision.
*
* Rev 1.1 Jul 20 2004 16:50:32 PattamattaD
* Updated comments.
*
* Rev 1.0 Jun 25 2004 14:26:14 PattamattaD
* Initial revision.
*
*
*
***********************************************************************
*
* Copyright (c) 2004 Sharp Microelectronics of the Americas
*
* All rights reserved
*
* 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.
*
**********************************************************************/
#include "lh79524_chip.h"
#include "lh79524_rcpc.h"
#include "lh79524_iocon.h"
#include "lh79524_clcdc_driver.h"
/***********************************************************************
* LCD driver private data and types
**********************************************************************/
/* Defines for the ip block base address and driver control object */
#define REGS_T CLCDC_REGS_T
#define TFT_REGS_T LCDICP_REGS_T
#define DRIVER_T CLCDC_T
#define N_DEVS N_LCDS
/* Private methods */
static void clcdc0_isr (void);
static void clcdc_default_isr (INT_32 devid);
static BOOL_32 lcd_initialize (INT_32 devid);
static void lcd_iocon_init (void);
static void lcd_iocon_init_tft (void);
/* Table of device base addresses */
static UNS_32 driverid[N_DEVS] =
{
/* base Address */
LCD_BASE
};
/* Instansiations of the driver control object */
static DRIVER_T driver[N_DEVS];
/* Address of the driver control objects */
static DRIVER_T* pdriver[N_DEVS] =
{
(DRIVER_T*)&driver[0]
};
/* Address of the driver interrupt handlers */
static void* driver_isr[N_DEVS] =
{
(void*)clcdc0_isr
};
/***********************************************************************
* CLCDC driver public functions
**********************************************************************/
/***********************************************************************
*
* Function: lcd_open
*
* Purpose: Open the LCD
*
* Processing:
* If init is not FALSE, return 0x00000000 to the caller. Otherwise,
* set init to TRUE, save the LCD peripheral register set address,
* disable the LCD, and check the arg value. If arg is not 0, then
* call the lcd_initialize with the value of arg as its parameter.
* Return a pointer to the LCD config structure to the caller. TBD
*
* Parameters:
* ipbase: LCD descriptor device address
* arg : Not used
*
* Outputs: None
*
* Returns: The pointer to a LCD config structure or 0
*
* Notes: None
*
**********************************************************************/
INT_32 lcd_open (INT_32 ipbase,
INT_32 arg)
{
INT_32 dev_exists = FALSE;
INT_32 devid = 0;
CHAR* dst = NULL;
INT_32 idx = 0;
REGS_T* pregs = NULL;
DRIVER_T* pdev = NULL;
CLCDC_SETTINGS_T* lcdcfg = (CLCDC_SETTINGS_T*)arg;
/* Find the device in the driver table */
for (devid = 0; devid < NELEMENTS(driverid); devid++)
{
/* Do we have a match */
if (ipbase == driverid[devid])
{
/* Found the device */
dev_exists = TRUE;
break;
}
}
/* Check to make sure that the device exists */
if (dev_exists == FALSE)
{
return (0);
}
/* Attach to the base address of the device */
pdev = (DRIVER_T*)pdriver[devid];
/* Make sure the device is not already opened */
if (pdev->init == TRUE)
{
/* Device has already been opened */
return (0);
}
/* Clear the driver control structure */
dst = (CHAR*)pdev;
for (idx = 0; idx < sizeof(DRIVER_T); idx++)
{
*dst++ = 0;
}
/* Set LCD clock same as HCLK and the enable LCD clock in RCPC */
RCPC->lcdclkprescale = RCPC_PRESCALER_DIV1;
RCPC->periphclkctrl1 &= ~RCPC_CLKCTRL1_LCD_DISABLE;
RCPC->ahbclkctrl &= ~RCPC_AHBCLKCTRL_LCD_DISABLE;
pdev->clcdclk = RCPC_GET_HCLK(lcdcfg->board_xtal_in);
/* Enable LCD pins in IOCON registers */
if(lcdcfg->lcdparam->lcd_panel_type == TFT)
{
lcd_iocon_init_tft();
}
else
{
lcd_iocon_init();
}
/* Enable LCD pins in IOCON registers */
//lcd_iocon_init();
/* Attach to the base address of the selected device */
pdev->regs = (void*)driverid[devid];
pdev->tft = (void*)ALI_BASE;
pdev->cfg = (void*)arg;
pregs = (REGS_T*)pdev->regs;
/* Disable the controller */
pregs->lcdctrl &= ~CLCDC_LCDCTRL_ENABLE;
/* make sure the CLCDC's DMA will only accesses memory on the AHB */
pregs->lcdupbase = INTERNAL_SRAM_BASE;
pregs->lcdlpbase = INTERNAL_SRAM_BASE;
/* Save the default rtc interrupt service routine */
pdev->irq_hdlr = driver_isr[devid];
/* 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)
{
(void) lcd_initialize ((INT_32)pdev);
}
/* Mark the device as initialized */
pdev->init = TRUE;
/* Return the device id */
return ((INT_32)pdev);
}
/***********************************************************************
*
* 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
*
* Notes: None
*
**********************************************************************/
STATUS lcd_close (INT_32 devid)
{
STATUS status = _NO_ERROR;
INT_32 idx = 0;
CHAR* dst = NULL;
DRIVER_T* pdev = NULL;
REGS_T* pregs = NULL;
/* Sanity check */
if (devid == 0)
{
/* device not opened or non-valid file handle */
return (_ERROR);
}
/* Bind to the device control structure */
pdev = (DRIVER_T*)devid;
pregs = (REGS_T*)pdev->regs;
/* Make sure the device is already opened */
if (pdev->init == FALSE)
{
return (_ERROR);
}
/* Reset the device */
pregs->lcdctrl &= ~CLCDC_LCDCTRL_ENABLE;
/* Invalidate the device */
pdev->init = FALSE;
/* Disable LCD clock in RCPC */
RCPC->periphclkctrl1 |= RCPC_CLKCTRL1_LCD_DISABLE;
RCPC->ahbclkctrl |= RCPC_AHBCLKCTRL_LCD_DISABLE;
/* Clear the serial driver control structure */
dst = (CHAR*)pdev;
for (idx = 0; idx < sizeof (DRIVER_T); idx++)
{
*dst++ = 0;
}
/* Device is closed */
return (status);
}
/***********************************************************************
*
* Function: lcd_read
*
* Purpose: LCD read function (stub only)
*
* Processing:
* Return 0 to the caller.
*
* Parameters:
* devid: Pointer to LCD config structure
* buffer: Pointer to data buffer to copy to
* max_bytes: Number of bytes to read
*
* Outputs: None
*
* Returns: Number of bytes actually read (always 0)
*
* Notes: None
*
**********************************************************************/
INT_32 lcd_read (INT_32 devid,
CHAR* buffer,
INT_32 max_bytes)
{
INT_32 n_bytes = 0;
/* Not implemented - use ioctl */
return (n_bytes);
}
/***********************************************************************
*
* Function: lcd_write
*
* Purpose: LCD write function (stub only)
*
* Processing:
* Return 0 to the caller.
*
* Parameters:
* devid: Pointer to LCD config structure
* buffer: Pointer to data buffer to copy from
* n_bytes: Number of bytes to write
*
* Outputs: None
*
* Returns: Number of bytes actually written (always 0)
*
* Notes: None
*
**********************************************************************/
INT_32 lcd_write (INT_32 devid,
CHAR* buffer,
INT_32 n_bytes)
{
INT_32 actual_bytes = 0;
/* Not implemented - use ioctl */
return (actual_bytes);
}
/***********************************************************************
*
* 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 real time clock
* parameter.
*
* Parameters:
* devid: Pointer to LCD config structure
* cmd: ioctl command
* arg: ioctl argument
*
* Outputs: None
*
* Returns: The status of the ioctl operation
*
* Notes: None
*
**********************************************************************/
STATUS lcd_ioctl (INT_32 devid,
INT_32 cmd,
INT_32 arg)
{
UNS_32 temp = 0;
STATUS status = _NO_ERROR;
REGS_T* pregs = NULL;
DRIVER_T* pdev = NULL;
/* Sanity check */
if (devid == 0)
{
/* Null pointer */
return (0);
}
/* Attach to the base address of the driver */
pdev = (DRIVER_T*)devid;
/* Make sure the device is already opened */
if (pdev->init == FALSE)
{
return (_ERROR);
}
/* Attach to the base address of the selected timer */
pregs = (REGS_T*)pdev->regs;
/* Validate the request */
switch (cmd)
{
case LCD_ENABLE:
/* Enable */
temp = pregs->lcdctrl;
temp |= CLCDC_LCDCTRL_ENABLE;
pregs->lcdctrl = temp;
break;
case LCD_DISABLE:
/* Disable */
temp = pregs->lcdctrl;
temp &= ~CLCDC_LCDCTRL_ENABLE;
pregs->lcdctrl = temp;
break;
case LCD_PW_ENABLE:
/* Enable LCD power */
temp = pregs->lcdctrl;
temp |= (CLCDC_LCDCTRL_ENABLE | CLCDC_LCDCTRL_PWR);
pregs->lcdctrl = temp;
break;
case LCD_PW_DISABLE:
/* Enable LCD power */
temp = pregs->lcdctrl;
temp &= ~(CLCDC_LCDCTRL_ENABLE | CLCDC_LCDCTRL_PWR);
pregs->lcdctrl = temp;
break;
case LCD_SET_FB:
/* Sanity check */
if (arg == 0)
{
/* Null pointer */
status = _ERROR;
break;
}
/* Set frame buffer address */
pregs->lcdupbase = (UNS_32)arg;
break;
case LCD_GET_STATUS:
/* Sanity check */
if (arg == 0)
{
/* Null pointer */
status = _ERROR;
break;
}
*(INT_32*)arg = pregs->lcdctrl & CLCDC_LCDCTRL_ENABLE;
break;
/* Mask interrupts at the source */
case LCD_DISABLE_INT:
/* Get the current state */
temp = pregs->lcdintrenable;
/* Mask off the interrupt */
temp &= ~arg;
/* Update the driver control object */
pdev->imask = temp;
/* Update the interrupt control register */
pregs->lcdintrenable = temp;
break;
/* Unmask interrupts at the source */
case LCD_ENABLE_INT:
/* Get the current state */
temp = pregs->lcdintrenable;
/* UnMask the interrupt */
temp |= arg;
/* Update the driver control object */
pdev->imask = temp;
/* Update the interrupt control register */
pregs->lcdintrenable = temp;
break;
case LCD_ENABLE_VCOMP_INT:
/* Get the current state */
temp = pregs->lcdctrl;
/* Clear the current vcomp bit field B[13:12] */
temp &= ~_SBF(12,3);
/* Update the current vcomp bit field B[13:12] */
temp |= _SBF(12,arg);
/* Write the new value to the control register */
pregs->lcdctrl = temp;
break;
case LCD_DISABLE_VCOMP_INT:
/* Get the current state */
temp = pregs->lcdctrl;
/* Clear the current vcomp bit field B[13:12] */
temp &= ~_SBF(12,3);
/* Write the new value to the control register */
pregs->lcdctrl = temp;
break;
case LCD_SET_RGB:
/* Get the current state */
temp = pregs->lcdctrl;
/* Set the BGR bit field B[8] */
temp |= CLCDC_LCDCTRL_RGB;
/* Write the new value to the control register */
pregs->lcdctrl = temp;
break;
case LCD_SET_BGR:
/* Get the current state */
temp = pregs->lcdctrl;
/* Clear the BGR bit field B[8] */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -