rt-thread-official/bsp/lpc408x/Libraries/Drivers/source/lpc_lcd.c

857 lines
24 KiB
C
Raw Normal View History

2014-01-02 18:30:13 +08:00
/**********************************************************************
* $Id$ lpc_lcd.c 2011-10-14
*//**
* @file lpc_lcd.c
* @brief Contains all functions support for LCD firmware library
* on LPC
* @version 1.0
* @date 14. October. 2011
* @author NXP MCU SW Application Team
*
* Copyright(C) 2011, NXP Semiconductor
* All rights reserved.
*
***********************************************************************
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* products. This software is supplied "AS IS" without any warranties.
* NXP Semiconductors assumes no responsibility or liability for the
* use of the software, conveys no license or title under any patent,
* copyright, or mask work right to the product. NXP Semiconductors
* reserves the right to make changes in the software without
* notification. NXP Semiconductors also make no representation or
* warranty that such application will be suitable for the specified
* use without further testing or modification.
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors'
* relevant copyright in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
**********************************************************************/
#ifdef __BUILD_WITH_EXAMPLE__
#include "lpc_libcfg.h"
#else
#include "lpc_libcfg_default.h"
#endif /* __BUILD_WITH_EXAMPLE__ */
#ifdef _LCD
#include "lpc_clkpwr.h"
#include "lpc_pinsel.h"
#include "lpc_gpio.h"
#include "lpc_lcd.h"
uint32_t lcd_hsize = 0, lcd_vsize = 0;
uint32_t lcd_cursor_base_addr = 0;
uint32_t lcd_cursor_size = 64;
LCD_Config_Type lcd_config;
static uint8_t bits_per_pixel[] = { 1, 2, 4, 8, 16, 32, 16, 16 };
uint32_t rect[1024];
static void LCD_SetHorizontalTiming(LCD_HConfig_Type* pConfig);
static void LCD_SetVertialTiming(LCD_VConfig_Type* pConfig);
static void LCD_SetPolarity(LCD_TYPES lcd_type, LCD_POLARITY_Type* pConfig);
static void LCD_CtrlSetup(LCD_Config_Type* pConfig);
/** @addtogroup LCD_Private_Functions LCD Private Function
* @ingroup LCD
* @{
*/
/*********************************************************************//**
* @brief Init LCD. The input clock is CClk
*
* @param[in] pConfig Configuration Information
*
* @return LCD_FUNC_OK Execute successfully
* LCD_FUNC_ERR Error occurred.
*
**********************************************************************/
LCD_RET_CODE LCD_Init (LCD_Config_Type* pConfig)
{
uint8_t clkdiv;
if(pConfig == NULL)
return LCD_FUNC_ERR;
if(pConfig->big_endian_byte & !pConfig->big_endian_pixel)
return LCD_FUNC_ERR;
lcd_config = *pConfig;
// Assign pins
PINSEL_ConfigPin(0,4,7);
PINSEL_ConfigPin(0,5,7);
PINSEL_ConfigPin(0,6,7);
PINSEL_ConfigPin(0,7,7);
PINSEL_ConfigPin(0,8,7);
PINSEL_ConfigPin(0,9,7);
PINSEL_ConfigPin(1,20,7);
PINSEL_ConfigPin(1,21,7);
PINSEL_ConfigPin(1,22,7);
PINSEL_ConfigPin(1,23,7);
PINSEL_ConfigPin(1,24,7);
PINSEL_ConfigPin(1,25,7);
PINSEL_ConfigPin(1,26,7);
PINSEL_ConfigPin(1,27,7);
PINSEL_ConfigPin(1,28,7);
PINSEL_ConfigPin(1,29,7);
PINSEL_ConfigPin(2,0,7);
PINSEL_ConfigPin(2,1,7);
PINSEL_ConfigPin(2,2,7);
PINSEL_ConfigPin(2,3,7);
PINSEL_ConfigPin(2,4,7);
PINSEL_ConfigPin(2,5,7);
PINSEL_ConfigPin(2,6,7);
#ifdef CORE_M4
PINSEL_ConfigPin(0,10,7);
#else
PINSEL_ConfigPin(2,7,7);
#endif
PINSEL_ConfigPin(2,8,7);
PINSEL_ConfigPin(2,9,7);
PINSEL_ConfigPin(2,11,7);
PINSEL_ConfigPin(2,12,7);
PINSEL_ConfigPin(2,13,7);
PINSEL_ConfigPin(4,28,7);
PINSEL_ConfigPin(4,29,7);
//Turn on LCD clock
CLKPWR_ConfigPPWR(CLKPWR_PCONP_PCLCD, ENABLE);
// Set clock
LPC_LCD->POL &= ~(0x01 << 5);
if( pConfig->panel_clk > 0) {
clkdiv = CLKPWR_GetCLK(CLKPWR_CLKTYPE_CPU) / pConfig->panel_clk - 1;
LPC_SC->LCD_CFG = clkdiv & 0x1F;
LPC_LCD->POL |=(1<<26);
}
// init Horizontal Timing
LCD_SetHorizontalTiming(&pConfig->hConfig);
// Init Vertical Timing
LCD_SetVertialTiming(&pConfig->vConfig);
// Set Polarity
LCD_SetPolarity(pConfig->lcd_type, &pConfig->polarity);
if(NULL != pConfig->lcd_palette)
{
LCD_SetPalette(pConfig->lcd_palette);
}
// Set Base address
LCD_SetBaseAddress(LCD_PANEL_UPPER, pConfig->lcd_panel_upper);
LCD_SetBaseAddress(LCD_PANEL_LOWER, pConfig->lcd_panel_lower);
// Setup
LCD_CtrlSetup(pConfig);
return LCD_FUNC_OK;
}
/*********************************************************************//**
* @brief Horizontal Timing Setting
*
* @param[in] pConfig Configuration Information
*
* @return None.
*
**********************************************************************/
void LCD_SetHorizontalTiming(LCD_HConfig_Type* pConfig)
{
LPC_LCD->TIMH = 0; //reset TIMH before set value
LPC_LCD->TIMH |= ((pConfig->hbp - 1)& 0xFF)<<24;
LPC_LCD->TIMH |= ((pConfig->hfp - 1)& 0xFF)<<16;
LPC_LCD->TIMH |= ((pConfig->hsw - 1)& 0xFF)<<8;
LPC_LCD->TIMH |= ((pConfig->ppl/16 - 1)& 0x3F)<<2;
lcd_hsize = pConfig->ppl;
}
/*********************************************************************//**
* @brief Vertical Timing Setting
*
* @param[in] pConfig Configuration Information
*
* @return None.
*
**********************************************************************/
void LCD_SetVertialTiming(LCD_VConfig_Type* pConfig)
{
LPC_LCD->TIMV = 0; //reset TIMV value before setting
LPC_LCD->TIMV |= ((pConfig->vbp)& 0xFF)<<24;
LPC_LCD->TIMV |= ((pConfig->vfp)& 0xFF)<<16;
LPC_LCD->TIMV |= ((pConfig->vsw - 1)& 0x3F)<<10;
LPC_LCD->TIMV |= ((pConfig->lpp - 1)& 0x03FF)<<0;
lcd_vsize = pConfig->lpp;
}
/*********************************************************************//**
* @brief Polarity Setting
*
* @param[in] pConfig Configuration Information
* @param[in] lcd_type It can be:
* - LCD_STN_MONOCHROME
* - LCD_STN_COLOR
* - LCD_TFT
*
* @return None.
*
**********************************************************************/
void LCD_SetPolarity(LCD_TYPES lcd_type, LCD_POLARITY_Type* pConfig)
{
// LCDFP pin is active LOW and inactive HIGH
if(pConfig->invert_vsync)
LPC_LCD->POL |= (1<<11);
else
LPC_LCD->POL &= ~(1<<11);
// LCDLP pin is active LOW and inactive HIGH
if(pConfig->invert_hsync)
LPC_LCD->POL |= (1<<12);
else
LPC_LCD->POL &= ~(1<<12);
// data is driven out into the LCD on the falling edge
if(pConfig->invert_panel_clock)
LPC_LCD->POL |= (1<<13);
else
LPC_LCD->POL &= ~(1<<13);
// active high
if(pConfig->active_high) {
LPC_LCD->POL &= ~(1<<14);
}
else
{
LPC_LCD->POL |= (1<<14);
}
LPC_LCD->POL &= ~(0x3FF <<16);
LPC_LCD->POL |= (pConfig->cpl - 1)<<16;
if(lcd_type == LCD_STN_COLOR || lcd_type == LCD_STN_MONOCHROME)
LPC_LCD->POL |= (pConfig->acb & 0x1F) << 6;
}
/*********************************************************************//**
* @brief Set base address of frame buffer
*
* @param[in] panel identify which panel is.
* @param[in] pAddress base address of the inputted panel.
*
* @return None.
*
**********************************************************************/
void LCD_SetBaseAddress(LCD_PANEL panel, uint32_t pAddress)
{
// Frame Base Address doubleword aligned
if(panel == LCD_PANEL_UPPER)
LPC_LCD->UPBASE = pAddress & ~7UL ;
else
LPC_LCD->LPBASE = pAddress & ~7UL ;
}
/*********************************************************************//**
* @brief LCD Setup.
*
* @param[in] pConfig Configuration information.
*
* @return None.
*
**********************************************************************/
void LCD_CtrlSetup(LCD_Config_Type* pConfig)
{
// disable LCD controller
LPC_LCD->CTRL = 0;
// bpp
LPC_LCD->CTRL &= ~(0x07 <<1);
LPC_LCD->CTRL |=((pConfig->lcd_bpp & 0x07)<<1);
if(pConfig->lcd_type == LCD_TFT) {
LPC_LCD->CTRL |= (0x01 << 5); // TFT
}
else {
// Color/Mono
if(pConfig->lcd_type == LCD_STN_COLOR) {
LPC_LCD->CTRL &= ~ (0x01 << 4); // Color
}
else if (pConfig->lcd_type == LCD_STN_MONOCHROME) {
LPC_LCD->CTRL |= (0x01 << 4); // Mono
}
// STN/TFT
LPC_LCD->CTRL &= ~ (0x01 << 5); // STN
// Mono4/8
if(pConfig->lcd_mono8)
LPC_LCD->CTRL |= (0x01 << 6);
else
LPC_LCD->CTRL &= ~(0x01 << 6);
// Single/dual
if(pConfig->lcd_dual)
LPC_LCD->CTRL |= (0x01 << 7);
else
LPC_LCD->CTRL &= ~(0x01 << 7);
}
// notmal output
if(pConfig->lcd_bgr)
LPC_LCD->CTRL |= (1<<8); // BGR
else
LPC_LCD->CTRL &= ~(1<<8); // RGB
// Byte order
if(pConfig->big_endian_byte)
LPC_LCD->CTRL |= (1<<9);
else
LPC_LCD->CTRL &= ~(1<<9);
// Pixel order
if(pConfig->big_endian_pixel)
LPC_LCD->CTRL |= (1<<10);
else
LPC_LCD->CTRL &= ~(1<<10);
// disable power
LPC_LCD->CTRL &= ~(1<<11);
}
/*********************************************************************//**
* @brief Enable/disable LCD Display.
*
* @param[in] bEna 0: disable, 1: enable.
*
* @return None.
*
**********************************************************************/
void LCD_Enable (Bool bEna)
{
volatile uint32_t i;
if (bEna)
{
LPC_LCD->CTRL |= (1<<0);
for(i = LCD_PWR_ENA_DIS_DLY; i; i--);
LPC_LCD->CTRL |= (1<<11);
}
else
{
LPC_LCD->CTRL &= ~(1<<11);
for(i = LCD_PWR_ENA_DIS_DLY; i; i--);
LPC_LCD->CTRL &= ~(1<<0);
}
}
/*********************************************************************//**
* @brief Set palette.
*
* @param[in] bEna 0: disable, 1: enable.
*
* @return None.
*
**********************************************************************/
void LCD_SetPalette (const uint8_t* pPallete)
{
uint32_t i;
uint32_t size = (0x01 << bits_per_pixel[lcd_config.lcd_bpp])/2 ;
uint32_t * pDst = (uint32_t *)LPC_LCD->PAL;
uint32_t * pInput = (uint32_t*) pPallete;
for (i = 0; i < size; i++)
{
*pDst = *pInput;
pDst++;
pInput++;
}
}
/*********************************************************************//**
* @brief Get word offset for the given pixel
*
* @param[in] x x position of input pixel
* @param[in] y y position of input pixel
*
* @return Offset
*
**********************************************************************/
uint32_t LCD_GetWordOffset(uint32_t x, uint32_t y)
{
uint32_t pixel_num = x + y*lcd_hsize;
return (pixel_num * bits_per_pixel[lcd_config.lcd_bpp])/32;
}
/*********************************************************************//**
* @brief Get bit offset for the given pixel
*
* @param[in] x x position of input pixel
* @param[in] y y position of input pixel
*
* @return Offset
*
**********************************************************************/
uint32_t LCD_GetBitOffset(uint32_t x, uint32_t y)
{
uint32_t pixel_num;
uint32_t ofs;
pixel_num = x + y*lcd_hsize;
ofs = (pixel_num * bits_per_pixel[lcd_config.lcd_bpp])%32;
if(lcd_config.big_endian_pixel & lcd_config.big_endian_byte)
{
ofs = 32 - bits_per_pixel[lcd_config.lcd_bpp] - ofs;
}
else if (lcd_config.big_endian_pixel & !lcd_config.big_endian_byte)
{
if(bits_per_pixel[lcd_config.lcd_bpp] < 8)
{
ofs = (ofs/8)*8 + (8 - (ofs%8)-bits_per_pixel[lcd_config.lcd_bpp]);
}
}
return ofs;
}
/*********************************************************************//**
* @brief Copy pixel values from image buffer to frame buffer.
*
* @param[in] panel It can be:
* - LCD_PANEL_UPPER
* - LCD_PANEL_LOWER
* @param[in] pPain point to image buffer.
*
* @return None.
*
**********************************************************************/
void LCD_SetImage(LCD_PANEL panel, const uint8_t *pPain)
{
volatile uint32_t i;
uint32_t * pWordDst = NULL;
uint8_t* pByteDst = NULL;
uint32_t bytes_num;
if(panel == LCD_PANEL_UPPER)
pWordDst = (uint32_t*) LPC_LCD->UPBASE;
else
pWordDst = (uint32_t*) LPC_LCD->LPBASE;
pByteDst = (uint8_t*) pWordDst;
bytes_num = ((lcd_hsize * lcd_vsize) * bits_per_pixel[lcd_config.lcd_bpp]) /8;
if (NULL == pPain)
{
// clear display memory
for( i = 0; bytes_num > i; i++)
{
*pByteDst++ = 0;
}
}
else
{
// set display memory
for(i = 0; bytes_num > i; i++)
{
*pByteDst++ = *pPain++;
}
}
for(i = LCD_PWR_ENA_DIS_DLY; i; i--);
}
/*********************************************************************//**
* @brief Draw a pixel on the given panel.
*
* @param[in] panel It can be:
* - LCD_PANEL_UPPER
* - LCD_PANEL_LOWER
* @param[in] X_Left X position.
* @param[in] Y_Up Y position.
* @param[in] color Color which is placed to the given pixel.
*
* @return None.
*
**********************************************************************/
void LCD_PutPixel (LCD_PANEL panel, uint32_t X_Left, uint32_t Y_Up, LcdPixel_t color)
{
uint32_t k;
uint32_t * pWordData = NULL;
uint8_t* pByteData = NULL;
uint32_t bitOffset;
uint8_t* pByteSrc = (uint8_t*)&color;
uint8_t bpp = bits_per_pixel[lcd_config.lcd_bpp];
uint8_t bytes_per_pixel = bpp/8;
uint32_t start_bit;
if((X_Left >= lcd_hsize)||(Y_Up >= lcd_vsize))
return;
if(panel == LCD_PANEL_UPPER)
pWordData = (uint32_t*) LPC_LCD->UPBASE + LCD_GetWordOffset(X_Left,Y_Up);
else
pWordData = (uint32_t*) LPC_LCD->LPBASE + LCD_GetWordOffset(X_Left,Y_Up);
bitOffset = LCD_GetBitOffset(X_Left,Y_Up);
pByteData = (uint8_t*) pWordData;
pByteData += bitOffset/8;
start_bit = bitOffset%8;
if(bpp < 8)
{
uint8_t bit_pos = start_bit;
uint8_t bit_ofs = 0;
for(bit_ofs = 0;bit_ofs <bpp; bit_ofs++,bit_pos++)
{
*pByteData &= ~ (0x01 << bit_pos);
*pByteData |= ((*pByteSrc >> (k+bit_ofs)) & 0x01) << bit_pos;
}
}
else
{
for(k = 0; k < bytes_per_pixel; k++)
{
*(pByteData+ k) = *pByteSrc++;
}
}
}
/*********************************************************************//**
* @brief Place given image to given position.
*
* @param[in] panel It can be:
* - LCD_PANEL_UPPER
* - LCD_PANEL_LOWER
* @param[in] X_Left Start X position.
* @param[in] Y_Up Start Y position.
* @param[in] pBmp Image information.
* @param[in] Mask Mask on pixel values.
*
* @return None.
*
**********************************************************************/
void LCD_LoadPic (LCD_PANEL panel, uint32_t X_Left, uint32_t Y_Up,
Bmp_t * pBmp, uint32_t Mask)
{
uint32_t i, j, k, inc;
uint32_t * pWordData = NULL;
uint8_t* pByteData = NULL;
uint32_t bitOffset;
uint8_t* pByteSrc = (uint8_t*) pBmp->pPicStream;
uint32_t X_LeftHold = X_Left;
uint8_t bpp = bits_per_pixel[lcd_config.lcd_bpp];
uint8_t bytes_per_pixel = bpp/8;
uint8_t pixels_per_byte = 8/bpp;
uint32_t hsize, vsize;
uint32_t start_bit;
if(pBmp->BytesPP == 0)
pBmp->BytesPP = bytes_per_pixel;
hsize = pBmp->H_Size;
vsize = pBmp->V_Size;
inc = (pixels_per_byte > 0) ? pixels_per_byte:1;
for(i = 0; i < vsize; i++)
{
if(panel == LCD_PANEL_UPPER)
pWordData = (uint32_t*) LPC_LCD->UPBASE + LCD_GetWordOffset(X_Left,Y_Up);
else
pWordData = (uint32_t*) LPC_LCD->LPBASE + LCD_GetWordOffset(X_Left,Y_Up);
bitOffset = LCD_GetBitOffset(X_Left,Y_Up);
pByteData = (uint8_t*) pWordData;
pByteData += bitOffset/8;
start_bit = bitOffset%8;
if(pBmp->BytesPP > 0)
pByteSrc = (uint8_t*) pBmp->pPicStream + i*hsize*pBmp->BytesPP; // storage of each line must be word alignment
else
pByteSrc = (uint8_t*) pBmp->pPicStream + (i*hsize*pBmp->BitsPP + 7)/8; // storage of each line must be word alignment
X_LeftHold = X_Left;
for(j = 0; j <= hsize; j+= inc)
{
if((X_LeftHold >= lcd_hsize) || (X_LeftHold - X_Left >= hsize))
break;
if(bpp < 8)
{
uint8_t bit_pos = start_bit;
uint8_t bit_ofs = 0;
for(k = 0; k < 8; k+= bpp)
{
for(bit_ofs = 0;bit_ofs <bpp; bit_ofs++,bit_pos++)
{
*pByteData &= ~ (0x01 << bit_pos);
*pByteData |= ((*pByteSrc >> (k+bit_ofs)) & 0x01) << bit_pos;
}
if(lcd_config.big_endian_byte && lcd_config.big_endian_pixel)
{
if(bit_pos >= bpp*2)
bit_pos -= bpp*2;
else
{
bit_pos = 8-bpp;
if((((uint32_t)pByteData)%4) == 0)
pByteData += 7; // change to next word
else
pByteData--; // change to previous byte
}
}
else if( !lcd_config.big_endian_byte && lcd_config.big_endian_pixel)
{
if(bit_pos >= bpp*2)
bit_pos -= bpp*2;
else
{
bit_pos = 8-bpp;
pByteData++; // change to next byte
}
}
else
{
if(bit_pos >= 8)
{
bit_pos = 0;
pByteData++; // change to next byte
}
}
X_LeftHold++;
if((X_LeftHold >= lcd_hsize) ||
(X_LeftHold - X_Left >= hsize))
break;
}
pByteSrc++;
continue;
}
else
{
for(k = 0; k < pBmp->BytesPP; k++)
{
*(pByteData+ k) = *pByteSrc++ ^ Mask;
}
if(lcd_config.big_endian_byte)
{
if((uint32_t)pByteData %4 > 0)
pByteData -= bytes_per_pixel;
else
pByteData += 8 - bytes_per_pixel;
}
else
pByteData+= bytes_per_pixel;
X_LeftHold++;
}
}
if(Y_Up++ >= lcd_vsize)
{
break;
}
}
}
/*********************************************************************//**
* @brief Fill a rectangle.
*
* @param[in] panel It can be:
* - LCD_PANEL_UPPER
* - LCD_PANEL_LOWER
* @param[in] startx Start X position.
* @param[in] endy End X position.
* @param[in] starty Start Y position.
* @param[in] endy End Y position.
*
* @return None.
*
**********************************************************************/
void LCD_FillRect (LCD_PANEL panel, uint32_t startx,uint32_t endx,
uint32_t starty, uint32_t endy,
LcdPixel_t color)
{
uint32_t x, xs, xe, ys, ye;
uint8_t bpp, pixels_per_word;
uint32_t word_val, mask;
uint32_t max_vsize = 0;
Bmp_t bitmap;
uint32_t hsize, vsize;
bpp = bits_per_pixel[lcd_config.lcd_bpp];
pixels_per_word = 32/bpp;
mask = 0;
for( x = 0; x < bpp; x++)
mask |= 0x01 << x;
color &= mask;
word_val = 0;
for(x = 0; x < pixels_per_word; x++)
word_val |= color << (x*bpp);
ys = (starty > endy) ? endy : starty;
ye = (starty > endy) ? starty : endy;
xs = (startx > endx) ? endx : startx;
xe = (startx > endx) ? startx : endx;
bitmap.BitsPP = bpp;
bitmap.BytesPP = bpp/8;
hsize = xe - xs + 1;
bitmap.H_Size = hsize;
vsize = ye - ys + 1;
bitmap.pPicStream = (uint8_t*)rect;
max_vsize = ((1024 * 32)/(hsize*bpp));
for( x = 0; x < 1024; x++)
{
rect[x] = word_val;
}
while(1)
{
if(max_vsize >= vsize)
{
bitmap.V_Size = vsize;
LCD_LoadPic(panel,xs,ys, &bitmap, 0);
break;
}
else {
bitmap.V_Size = max_vsize;
vsize -= bitmap.V_Size;
LCD_LoadPic(panel,xs,ys, &bitmap, 0);
ys += max_vsize;
}
}
}
/*********************************************************************//**
* @brief Configure display of cursor.
*
* @param[in] pConfig Configuration information.
*
* @return None.
*
**********************************************************************/
void LCD_Cursor_Cfg(LCD_Cursor_Config_Type* pConfig)
{
if(pConfig->size32) {
LPC_LCD->CRSR_CFG &= ~(0x01 << 0);
lcd_cursor_size = 32;
}
else {
LPC_LCD->CRSR_CFG |= (0x01 << 0);
lcd_cursor_size = 64;
}
if(pConfig->framesync)
LPC_LCD->CRSR_CFG &= ~(0x01 << 1);
else
LPC_LCD->CRSR_CFG |= (0x01 << 1);
lcd_cursor_base_addr = pConfig->baseaddress;
LPC_LCD->CRSR_PAL0 = pConfig->palette[0].Red |
pConfig->palette[0].Green << 8 |
pConfig->palette[0].Blue << 16;
LPC_LCD->CRSR_PAL1 = pConfig->palette[1].Red |
pConfig->palette[1].Green << 8 |
pConfig->palette[1].Blue << 16;
}
/*********************************************************************//**
* @brief Enable/disable cursor display.
*
* @param[in] enable 0: disable, 1: enable.
* @param[in] cursor identify which cursor image is used.
*
* @return None.
*
**********************************************************************/
void LCD_Cursor_Enable(int enable, int cursor)
{
if(enable) {
LPC_LCD->CRSR_CTRL |= (1<<0);
LPC_LCD->CRSR_CTRL |= (cursor<<4);
}
else {
LPC_LCD->CRSR_CTRL &= ~(1<<0);
}
}
/*********************************************************************//**
* @brief move the cursor to the inputted position.
*
* @param[in] x Position in x-direction.
* @param[in] y Position in y-direction.
*
* @return None.
*
**********************************************************************/
void LCD_Move_Cursor(int x, int y)
{
LPC_LCD->CRSR_CLIP = 0;
LPC_LCD->CRSR_XY = 0;
if(0 <= x)
{//no clipping
LPC_LCD->CRSR_XY |= (x & 0x3FF);
}
else
{//clip x
LPC_LCD->CRSR_CLIP |= -x;
}
if(0 <= y)
{//no clipping
LPC_LCD->CRSR_XY |= (y << 16);
}
else
{//clip y
LPC_LCD->CRSR_CLIP |= (-y << 8);
}
}
/*********************************************************************//**
* @brief Set the cursor image.
*
* @param[in] pCursor point to cursor image.
* @param[in] cursor cursor image number. It has no meaning when cursor size is 64x64
* @param[in] cursor cursor size in words.
*
* @return None.
*
**********************************************************************/
void LCD_Cursor_SetImage (const uint32_t *pCursor, int cursor, int size)
{
uint32_t i ;
uint32_t * pDst = (uint32_t *)lcd_cursor_base_addr;
if(lcd_cursor_size == 32)
pDst += cursor*GET_CURSOR_IMG_SIZE(lcd_cursor_size);
for(i = 0; i < size ; i++)
{
*pDst = *pCursor;
pDst++;
pCursor++;
}
}
/**
* @}
*/
#endif /*_LCD*/