Table of Contents

Nokia 6610 LCD driver

Texas Instruments (Luminary Micro) StellarisWare Graphics Library driver for Nokia 6610 LCD display with backlight.

nokia6610.c

//*****************************************************************************
//
// nokia6610.c - Driver for the Nokia 6610 graphical LCD display.
//
// Copyright (c) 2010 TUT Department of Mechatronics.
// Based on the work of James P Lynch.
// 
// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. AUTHOR SHALL NOT, UNDER ANY
// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
// DAMAGES, FOR ANY REASON WHATSOEVER.
//
//*****************************************************************************
 
//*****************************************************************************
//
//! \addtogroup display_api
//! @{
//
//*****************************************************************************
 
#include "inc/hw_ssi.h"
#include "inc/hw_memmap.h"
#include "inc/hw_sysctl.h"
#include "inc/hw_types.h"
#include "driverlib/debug.h"
#include "driverlib/gpio.h"
#include "driverlib/ssi.h"
#include "driverlib/sysctl.h"
#include "grlib/grlib.h"
#include "drivers/nokia6610.h"
#include "drivers/general.h"
#include "drivers/rgb_led.h"
 
//*****************************************************************************
//
// Macros that define the peripheral, port, and pin used for the OLEDDC
// panel control signal.
//
//*****************************************************************************
#define SYSCTL_PERIPH_GPIO_OLEDDC   SYSCTL_PERIPH_GPIOA
#define GPIO_LCD_BASE               GPIO_PORTA_BASE
#define GPIO_LCD_RST_PIN            GPIO_PIN_6
#define GPIO_LCD_BL_PIN             GPIO_PIN_7
 
//*****************************************************************************
//
// Display configuration.
//
//*****************************************************************************
#define SCREEN_OFFSET_X  0
#define SCREEN_OFFSET_Y  2
#define SCREEN_WIDTH     130
#define SCREEN_HEIGHT    130
 
//*****************************************************************************
//
//			PHILLIPS Controller Definitions
//
//*****************************************************************************
#ifdef DRIVER_PHILIPS
 
#define NOP           0x00     // nop
#define SOFTRST       0x01     // software reset
#define BOOSTVOFF     0x02     // booster voltage OFF
#define BOOSTVON      0x03     // booster voltage ON
#define TESTMODE1     0x04     // test mode
#define DISPSTATUS    0x09     // display status
#define SLEEPIN       0x10     // sleep in
#define SLEEPOUT      0x11     // sleep out
#define PARTIAL       0x12     // partial display mode
#define NORMALMODE    0x13     // display normal mode
#define INVERSIONOFF  0x20     // inversion OFF
#define INVERSIONON   0x21     // inversion ON
#define ALLPIXELOFF   0x22     // all pixel OFF
#define ALLPIXELON    0x23     // all pixel ON
#define CONTRAST      0x25     // write contrast
#define DISPLAYOFF    0x28     // display OFF
#define DISPLAYON     0x29     // display ON
#define COLADDRSET    0x2A     // column address set
#define PAGEADDRSET   0x2B     // page address set
#define MEMWRITE      0x2C     // memory write
#define COLORSET      0x2D     // colour set
#define READRAMDATA   0x2E     // RAM data read
#define PARTIALAREA   0x30     // partial area
#define VERTSCROLL    0x33     // vertical scrolling definition
#define TESTMODE2     0x34     // test mode
#define TESTMODE3     0x35     // test mode
#define ACCESSCTRL    0x36     // memory access control
#define VSCRLSADDR    0x37     // vertical scrolling start address
#define IDLEOFF       0x38     // idle mode OFF
#define IDLEON        0x39     // idle mode ON
#define PIXELFORMAT   0x3A     // interface pixel format
#define TESTMODE4     0xDE     // test mode
#define NOP2          0xAA     // nop
#define INITESC       0xC6     // initial escape
#define TESTMODE5     0xDA     // test mode
#define TESTMODE6     0xDB     // test mode
#define TESTMODE7     0xDC     // test mode
#define TESTMODE8     0xB2     // test mode
#define GRAYSCALE0    0xB3     // gray scale position set 0
#define GRAYSCALE1    0xB4     // gray scale position set 1
#define GAMMA         0xB5     // gamma curve set
#define DISPCTRL      0xB6     // display control
#define TEMPGRADIENT  0xB7     // temp gradient set
#define TESTMODE9     0xB8     // test mode
#define REFSET        0xB9     // refresh set
#define VOLTCTRL      0xBA     // voltage control
#define COMMONDRV     0xBD     // common driver output select
#define PWRCTRL       0xBE     // power control
 
#endif
 
 
//*****************************************************************************
//
//					EPSON Controller Definitions
//
//*****************************************************************************
#ifdef DRIVER_EPSON
 
#define DISON         0xAF     // Display on
#define DISOFF        0xAE     // Display off
#define DISNOR        0xA6     // Normal display
#define DISINV        0xA7     // Inverse display
#define COMSCN        0xBB     // Common scan direction
#define DISCTL        0xCA     // Display control
#define SLPIN         0x95     // Sleep in
#define SLPOUT        0x94     // Sleep out
#define PASET         0x75     // Page address set
#define CASET         0x15     // Column address set
#define DATCTL        0xBC     // Data scan direction, etc.
#define RGBSET8       0xCE     // 256-color position set
#define RAMWR         0x5C     // Writing to memory
#define RAMRD         0x5D     // Reading from memory
#define PTLIN         0xA8     // Partial display in
#define PTLOUT        0xA9     // Partial display out
#define RMWIN         0xE0     // Read and modify write
#define RMWOUT        0xEE     // End
#define ASCSET        0xAA     // Area scroll set
#define SCSTART       0xAB     // Scroll start set
#define OSCON         0xD1     // Internal oscillation on
#define OSCOFF        0xD2     // Internal oscillation off
#define PWRCTR        0x20     // Power control
#define VOLCTR        0x81     // Electronic volume control
#define VOLUP         0xD6     // Increment electronic control by 1
#define VOLDOWN       0xD7     // Decrement electronic control by 1
#define TMPGRD        0x82     // Temperature gradient set
#define EPCTIN        0xCD     // Control EEPROM
#define EPCOUT        0xCC     // Cancel EEPROM control
#define EPMWR         0xFC     // Write into EEPROM
#define EPMRD         0xFD     // Read from EEPROM
#define EPSRRD1       0x7C     // Read register 1
#define EPSRRD2       0x7D     // Read register 2
#define NOP           0x25     // NOP instruction
 
#endif
 
//*****************************************************************************
//
// Translates a 24-bit RGB color to a display driver-specific color.
//
// \param c is the 24-bit RGB color.  The least-significant byte is the blue
// channel, the next byte is the green channel, and the third byte is the red
// channel.
//
// This macro translates a 24-bit RGB color into a value that can be written
// into the display's frame buffer in order to reproduce that color, or the
// closest possible approximation of that color.
//
// \return Returns the display-driver specific color.
//
//*****************************************************************************
 
#define DPYCOLORTRANSLATE(c)    ((((c) & 0xF00000) >> 12) | \
                                 (((c) & 0x00F000) >>  8) | \
                                 (((c) & 0x0000F0) >>  4))
 
//*****************************************************************************
//
//! \internal
//!
//! Write a command byte to the LCD controller.
//!
//! \return None.
//
//*****************************************************************************
static void
WriteCommand(const unsigned char ucBuffer)
{
	unsigned long ulTemp;
 
	//
	// Write the byte to the controller.
	//
	SSIDataPut(SSI0_BASE, ucBuffer & 0xFF);
 
	//
	// Dummy read to drain the FIFO and time the GPIO signal.
	//
	SSIDataGet(SSI0_BASE, &ulTemp);	
}
 
//*****************************************************************************
//
//! \internal
//!
//! Write a data byte to the LCD controller.
//!
//! \return None.
//
//*****************************************************************************
static void
WriteData(const unsigned char ucBuffer)
{
	unsigned long ulTemp;
 
	//
	// Write the byte to the controller.
	//
	SSIDataPut(SSI0_BASE, ucBuffer | 0x100);
 
	//
	// Dummy read to drain the FIFO and time the GPIO signal.
	//
	SSIDataGet(SSI0_BASE, &ulTemp);	
}
 
//*****************************************************************************
//
//! Initialize the LCD display.
//!
//! \param ulFrequency specifies the SSI Clock Frequency to be used.
//!
//! This function initializes the SSI interface to the LCD display and
//! configures the LCD controller on the panel.
//!
//! \return None.
//
//*****************************************************************************
void
Nokia6610Init(unsigned long ulFrequency)
{
	unsigned long ulTemp;
 
	//
	// Enable the SSI0 and GPIO port blocks as they are needed by this driver.
	//	
	SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI0);
	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);    
 
	//
	// Configure the SSI0CLK and SSIOTX pins for SSI operation.
	//
	GPIOPinTypeSSI(GPIO_PORTA_BASE, GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5);
	GPIOPadConfigSet(GPIO_PORTA_BASE, GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5,
	                 GPIO_STRENGTH_8MA, GPIO_PIN_TYPE_STD_WPU);
 
	//
	// Configure the SSI0 port for master mode.
	//
	SSIConfigSetExpClk(SSI0_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_0,
	                   SSI_MODE_MASTER, ulFrequency, 9);
 
	//
	// Enable the SSI port.
	//
	SSIEnable(SSI0_BASE);
 
	//
	// Drain the receive fifo.
	//
	while(SSIDataGetNonBlocking(SSI0_BASE, &ulTemp) != 0)
	{
	}
 
	//
	// Configure the GPIO port pin used as a D/Cn signal for LCD device,
	// and the port pin used to enable power to the LCD panel.
	//
	GPIOPinTypeGPIOOutput(GPIO_LCD_BASE, GPIO_LCD_RST_PIN | GPIO_LCD_BL_PIN);
	GPIOPadConfigSet(GPIO_LCD_BASE, GPIO_LCD_RST_PIN | GPIO_LCD_BL_PIN,
	                 GPIO_STRENGTH_8MA, GPIO_PIN_TYPE_STD);
	GPIOPinWrite(GPIO_LCD_BASE, GPIO_LCD_RST_PIN | GPIO_LCD_BL_PIN, GPIO_LCD_RST_PIN);        
 
	//
	// Initialize the display controller.
	//	
	DelayMS(100);  
 
	//
	// Display control.
	// Default CL division and drive pattern, 132 lines, 10 highlighted lines
	//
	WriteCommand(DISCTL);
	WriteData(0x00);
	WriteData(0x20);
	WriteData(0x0A);
 
	//
	// COM scan 1-80.
	//
	WriteCommand(COMSCN);
	WriteData(0x00);
 
	//
	// Internal oscillator on.
	//
	WriteCommand(OSCON);
 
	//
	// Wait approximately 100 ms.
	//
	DelayMS(100);
 
	//
	// Out from sleep.
	//
	WriteCommand(SLPOUT);
 
	//
	// Voltage control.
	// Middle value of V1.
	// Middle value of resistance value.
	//
	WriteCommand(VOLCTR);
	WriteData(0x1F);    
	WriteData(0x03);      
 
	//
	// Default temperature gradient.
	//
	WriteCommand(TMPGRD);
	WriteData(0x00);
 
	//
	// Power control.
	// Reference voltage regulator on, circuit voltage follower on, boost on.
	//
	WriteCommand(PWRCTR);
	WriteData(0x0F);
 
	//
	// Normal display.
	//
	WriteCommand(DISNOR);
 
	//
	// Inverse display.
	//
	WriteCommand(DISINV);
 
	//
	// Partial area off.
	//
	WriteCommand(PTLOUT);	
 
	//
	// Data control.
	// all inversions off, column direction, RGB sequence, 16 bit grayscale.
	//
	WriteCommand(DATCTL);
	WriteData(0x00);
	WriteData(0x00);	
	WriteData(0x02);
 
	//
	// Turn on the display.
	//
	WriteCommand(DISON);
}
 
//*****************************************************************************
//
//! Turns on/off the LCD backlight.
//!
//! \return None.
//
//*****************************************************************************
void
Nokia6610Backlight(tBoolean bState)
{
	GPIOPinWrite(GPIO_LCD_BASE, GPIO_LCD_BL_PIN,
		(bState ? GPIO_LCD_BL_PIN : 0x00));
}
 
//*****************************************************************************
//
//! Draws a pixel on the screen.
//!
//! \param pvDisplayData is a pointer to the driver-specific data for this
//! display driver.
//! \param lX is the X coordinate of the pixel.
//! \param lY is the Y coordinate of the pixel.
//! \param ulValue is the color of the pixel.
//!
//! This function sets the given pixel to a particular color.  The coordinates
//! of the pixel are assumed to be within the extents of the display.
//!
//! \return None.
//
//*****************************************************************************
static void
Nokia6610PixelDraw(void *pvDisplayData, long lX, long lY,
                           unsigned long ulValue)
{
	//
	// Page column (X) set.
	//
	WriteCommand(CASET);
	WriteData(lX + SCREEN_OFFSET_X);
	WriteData(lX + SCREEN_OFFSET_X);
 
	//
	// Page address (Y) set.
	//
	WriteCommand(PASET);
	WriteData(lY + SCREEN_OFFSET_Y);
	WriteData(lY + SCREEN_OFFSET_Y);	
 
	//
	// Write memory.
	//    
	WriteCommand(RAMWR);		
 
	//
	// Write the pixel value.
	//
	WriteData(ulValue >> 4);
	WriteData((ulValue << 4) | (ulValue >> 8));
	WriteData(ulValue);
}
 
//*****************************************************************************
//
//! Draws a horizontal sequence of pixels on the screen.
//!
//! \param pvDisplayData is a pointer to the driver-specific data for this
//! display driver.
//! \param lX is the X coordinate of the first pixel.
//! \param lY is the Y coordinate of the first pixel.
//! \param lX0 is sub-pixel offset within the pixel data, which is valid for 1
//! or 4 bit per pixel formats.
//! \param lCount is the number of pixels to draw.
//! \param lBPP is the number of bits per pixel; must be 1, 4, or 8.
//! \param pucData is a pointer to the pixel data.  For 1 and 4 bit per pixel
//! formats, the most significant bit(s) represent the left-most pixel.
//! \param pucPalette is a pointer to the palette used to draw the pixels.
//!
//! This function draws a horizontal sequence of pixels on the screen, using
//! the supplied palette.  For 1 bit per pixel format, the palette contains
//! pre-translated colors; for 4 and 8 bit per pixel formats, the palette
//! contains 24-bit RGB values that must be translated before being written to
//! the display.
//!
//! \return None.
//
//*****************************************************************************
static void
Nokia6610PixelDrawMultiple(void *pvDisplayData, long lX, long lY,
                                   long lX0, long lCount, long lBPP,
                                   const unsigned char *pucData,
                                   const unsigned char *pucPalette)
{
	unsigned long ulByte;
	unsigned long ucNextByte = 0;
 
	//
	// Page column (X) set.
	//
	WriteCommand(CASET);
	WriteData(lX + SCREEN_OFFSET_X);
	WriteData(lX + SCREEN_OFFSET_X + lCount - 1);	
 
	//
	// Page address (Y) set.
	//
	WriteCommand(PASET);
	WriteData(lY + SCREEN_OFFSET_Y);
	WriteData(lY + SCREEN_OFFSET_Y);
 
	//
	// Write memory.
	//
	WriteCommand(RAMWR);
 
	//
	// Determine how to interpret the pixel data based on the number of bits
	// per pixel.
	//
	switch(lBPP)
	{
		//
		// The pixel data is in 1 bit per pixel format.
		//
		// NB! Not tested!
		//
		case 1:
		{
			//
			// Loop while there are more pixels to draw.
			//
			while(lCount)
			{
					//
					// Get the next byte of image data.
					//
					ulByte = *pucData++;
 
					//
					// Loop through the pixels in this byte of image data.
					//
					while((lX0 < 8) && lCount)
					{
					//
					// Draw this pixel in the appropriate color.
					//
					lBPP = ((unsigned long *)pucPalette)[(ulByte >>
					                                      (7 - lX0)) & 1];
					WriteData(lBPP >> 4);                    
					ucNextByte = lBPP << 4;        		
 
					//
					// Decrement the count of pixels to draw.
					//
					lCount--;
					lX0++;					
 
					//
					// See if there is another pixel to draw.
					//
					if((lX0 < 8) && lCount)
					{	
						//
						// Draw this pixel in the appropriate color.
						//
						lBPP = ((unsigned long *)pucPalette)[(ulByte >>
						                                      (7 - lX0)) & 1];
						WriteData(ucNextByte | (lBPP >> 8));
						WriteData(lBPP);
 
						//
						// Decrement the count of pixels to draw.
						//
						lCount--;
						lX0++;
					}
					else
					{
						//
						// Complete the last pixel.
						//
						WriteData(ucNextByte);
					}
				}
 
			    //
			    // Start at the beginning of the next byte of image data.
			    //
			    lX0 = 0;
			}
 
			//
			// The image data has been drawn.
			//
			break;
		}
 
		//
		// The pixel data is in 4 bit per pixel format.
		//
		case 4:
		{
			//
			// Loop while there are more pixels to draw.  "Duff's device" is
			// used to jump into the middle of the loop if the first nibble of
			// the pixel data should not be used.  Duff's device makes use of
			// the fact that a case statement is legal anywhere within a
			// sub-block of a switch statement.  See
			// http://en.wikipedia.org/wiki/Duff's_device for detailed
			// information about Duff's device.
			//
			switch(lX0 & 1)
			{
			    case 0:
			        while(lCount)
			        {
			            //
			            // Get the upper nibble of the next byte of pixel data
			            // and extract the corresponding entry from the
			            // palette.
			            //
			            ulByte = (*pucData >> 4) * 3;
			            ulByte = (*(unsigned long *)(pucPalette + ulByte) &
			                      0x00ffffff);
 
			            //
			            // Translate this palette entry and write it to the
			            // screen.
			            //
			            ulByte = DPYCOLORTRANSLATE(ulByte);
						WriteData(ulByte >> 4);
						ucNextByte = ulByte << 4;        				
 
			            //
			            // Decrement the count of pixels to draw.
			            //
			            lCount--;
 
			            //
			            // See if there is another pixel to draw.
			            //
			            if(lCount)
			            {
			    case 1:
			                //
			                // Get the lower nibble of the next byte of pixel
			                // data and extract the corresponding entry from
			                // the palette.
			                //
			                ulByte = (*pucData++ & 15) * 3;
			                ulByte = (*(unsigned long *)(pucPalette + ulByte) &
			                          0x00ffffff);
 
			                //
			                // Translate this palette entry and write it to the
			                // screen.
			                //
			                ulByte = DPYCOLORTRANSLATE(ulByte);
			                WriteData(ucNextByte | (ulByte >> 8));
			                WriteData(ulByte);
 
			                //
			                // Decrement the count of pixels to draw.
			                //
			                lCount--;
			            }
						else
						{
							//
							// Complete the last pixel.
							//
							WriteData(ucNextByte);
						}
			        }
			}
 
		    //
		    // The image data has been drawn.
		    //
		    break;
		}
 
		//
		// The pixel data is in 8 bit per pixel format.
		//
		// NB! Not tested!
		//
		case 8:
		{
		    //
		    // Loop while there are more pixels to draw.
		    //
		    while(lCount)
		    {				
		        //
		        // Get the next byte of pixel data and extract the
		        // corresponding entry from the palette.
		        //
		        ulByte = *pucData++ * 3;
		        ulByte = *(unsigned long *)(pucPalette + ulByte) & 0x00ffffff;
 
		        //
		        // Translate this palette entry and write it to the screen.
		        //
		        ulByte = DPYCOLORTRANSLATE(ulByte);
		        WriteData(ulByte >> 4);
				ucNextByte = ulByte << 4;  
 
				//
		        // Decrement the count of pixels to draw.
		        //
		        lCount--;
 
				//
		        // See if there is another pixel to draw.
		        //
				if(lCount)
				{
					 //
		            // Get the next byte of pixel data and extract the
		            // corresponding entry from the palette.
		            //
		            ulByte = *pucData++ * 3;
		            ulByte = *(unsigned long *)(pucPalette + ulByte) & 0x00ffffff;
 
		            //
		            // Translate this palette entry and write it to the screen.
		            //
		            ulByte = DPYCOLORTRANSLATE(ulByte);
					WriteData(ucNextByte | (ulByte >> 8));
					WriteData(ulByte);                
 
					//
		            // Decrement the count of pixels to draw.
		            //
		            lCount--;
				}
				else
				{
					//
					// Complete the last pixel.
					//
					WriteData(ucNextByte);
				}
		    }
 
		    //
		    // The image data has been drawn.
		    //
		    break;
		}
	}
}
 
//*****************************************************************************
//
//! Draws a horizontal line.
//!
//! \param pvDisplayData is a pointer to the driver-specific data for this
//! display driver.
//! \param lX1 is the X coordinate of the start of the line.
//! \param lX2 is the X coordinate of the end of the line.
//! \param lY is the Y coordinate of the line.
//! \param ulValue is the color of the line.
//!
//! This function draws a horizontal line on the display.  The coordinates of
//! the line are assumed to be within the extents of the display.
//!
//! \return None.
//
//*****************************************************************************
static void
Nokia6610LineDrawH(void *pvDisplayData, long lX1, long lX2, long lY,
                           unsigned long ulValue)	
{
	long lCount;
 
	//
	// Page column (X) set.
	//
	WriteCommand(CASET);
	WriteData(lX1 + SCREEN_OFFSET_X);
	WriteData(lX2 + SCREEN_OFFSET_X);	
 
	//
	// Page address (Y) set.
	//
	WriteCommand(PASET);
	WriteData(lY + SCREEN_OFFSET_Y);
	WriteData(lY + SCREEN_OFFSET_Y);
 
    //
	// Write memory.
	//
	WriteCommand(RAMWR);    
 
	//
    // Count number of pixel pairs + 1
    //
	lCount = (lX2 - lX1 + 1) / 2 + 1;
 
	//
    // Loop through the pixels of this horizontal line.
    //
	while(lCount--)
	{		        
        WriteData(ulValue >> 4);
        WriteData((ulValue << 4) | (ulValue >> 8));
		WriteData(ulValue);
	}	
}
 
//*****************************************************************************
//
//! Draws a vertical line.
//!
//! \param pvDisplayData is a pointer to the driver-specific data for this
//! display driver.
//! \param lX is the X coordinate of the line.
//! \param lY1 is the Y coordinate of the start of the line.
//! \param lY2 is the Y coordinate of the end of the line.
//! \param ulValue is the color of the line.
//!
//! This function draws a vertical line on the display.  The coordinates of the
//! line are assumed to be within the extents of the display.
//!
//! \return None.
//
//*****************************************************************************
static void
Nokia6610LineDrawV(void *pvDisplayData, long lX, long lY1, long lY2,
                           unsigned long ulValue)
{
	long lCount;
 
	//
	// Page column (X) set.
	//
	WriteCommand(CASET);
	WriteData(lX + SCREEN_OFFSET_X);
	WriteData(lX + SCREEN_OFFSET_X);	
 
	//
	// Page address (Y) set.
	//
	WriteCommand(PASET);
	WriteData(lY1 + SCREEN_OFFSET_Y);
	WriteData(lY2 + SCREEN_OFFSET_Y);
 
    //
	// Write memory.
	//
	WriteCommand(RAMWR);    
 
	//
    // Count number of pixel pairs + 1
    //
	lCount = (lY2 - lY1 + 1) / 2 + 1;
 
	//
    // Loop through the pixels of this vertical line.
    //
	while(lCount--)
	{		        
        WriteData(ulValue >> 4);
        WriteData((ulValue << 4) | (ulValue >> 8));
		WriteData(ulValue);		
	}
}
 
//*****************************************************************************
//
//! Fills a rectangle.
//!
//! \param pvDisplayData is a pointer to the driver-specific data for this
//! display driver.
//! \param pRect is a pointer to the structure describing the rectangle.
//! \param ulValue is the color of the rectangle.
//!
//! This function fills a rectangle on the display.  The coordinates of the
//! rectangle are assumed to be within the extents of the display, and the
//! rectangle specification is fully inclusive (in other words, both sXMin and
//! sXMax are drawn, along with sYMin and sYMax).
//!
//! \return None.
//
//*****************************************************************************
static void
Nokia6610RectFill(void *pvDisplayData, const tRectangle *pRect,
                          unsigned long ulValue)
{    
	long lCount;
 
	//
	// Page column (X) set.
	//
	WriteCommand(CASET);
	WriteData(pRect->sXMin + SCREEN_OFFSET_X);
	WriteData(pRect->sXMax + SCREEN_OFFSET_X);	
 
	//
	// Page address (Y) set.
	//
	WriteCommand(PASET);
	WriteData(pRect->sYMin + SCREEN_OFFSET_Y);
	WriteData(pRect->sYMax + SCREEN_OFFSET_Y);
 
    //
	// Write memory.
	//
	WriteCommand(RAMWR);
 
    //
    // Count number of pixel pairs + 1
    //
	lCount = ((pRect->sXMax - pRect->sXMin + 1) *
              (pRect->sYMax - pRect->sYMin + 1)) / 2 + 1;
 
	//
    // Loop through the pixels in this rectangle.
    //
	while(lCount--)
    {		        		
        WriteData(ulValue >> 4);
        WriteData((ulValue << 4) | (ulValue >> 8));				
		WriteData(ulValue);
	}	
}
 
//*****************************************************************************
//
//! Translates a 24-bit RGB color to a display driver-specific color.
//!
//! \param pvDisplayData is a pointer to the driver-specific data for this
//! display driver.
//! \param ulValue is the 24-bit RGB color.  The least-significant byte is the
//! blue channel, the next byte is the green channel, and the third byte is the
//! red channel.
//!
//! This function translates a 24-bit RGB color into a value that can be
//! written into the display's frame buffer in order to reproduce that color,
//! or the closest possible approximation of that color.
//!
//! \return Returns the display-driver specific color.
//
//*****************************************************************************
static unsigned long
Nokia6610ColorTranslate(void *pvDisplayData, unsigned long ulValue)
{
    //
    // Translate from a 24-bit RGB color to a 4-4-4-bit RGB color.
    //
    return(DPYCOLORTRANSLATE(ulValue));
}
 
//*****************************************************************************
//
//! Flushes any cached drawing operations.
//!
//! \param pvDisplayData is a pointer to the driver-specific data for this
//! display driver.
//!
//! This functions flushes any cached drawing operations to the display.  This
//! is useful when a local frame buffer is used for drawing operations, and the
//! flush would copy the local frame buffer to the display.  For the Nokia 6610
//! driver, the flush is a no operation.
//!
//! \return None.
//
//*****************************************************************************
static void
Nokia6610Flush(void *pvDisplayData)
{
    //
    // There is nothing to be done.
    //
}
 
//*****************************************************************************
//
//! The graphics library display structure that describes the driver for the
//! Nokia 6610 color panel with Philips or Epson controller.
//
//*****************************************************************************
const tDisplay g_sNokia6610 =
{
    sizeof(tDisplay),
    0,
    SCREEN_WIDTH,
    SCREEN_HEIGHT,
    Nokia6610PixelDraw,
    Nokia6610PixelDrawMultiple,
    Nokia6610LineDrawH,
    Nokia6610LineDrawV,
    Nokia6610RectFill,
    Nokia6610ColorTranslate,
    Nokia6610Flush
};
 
//*****************************************************************************
//
// Close the Doxygen group.
//! @}
//
//*****************************************************************************

nokia6610.h

//*****************************************************************************
//
// Nokia6610.h - Prototypes for the driver for the
//               Nokia 6610 graphical LCD display.
//
// Copyright (c) 2010 TUT Department of Mechatronics.
// Based on the work of James P Lynch.
// 
// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. AUTHOR SHALL NOT, UNDER ANY
// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
// DAMAGES, FOR ANY REASON WHATSOEVER.
//
//*****************************************************************************
 
#ifndef __NOKIA_6610_H__
#define __NOKIA_6610_H__
 
//*****************************************************************************
//
// Nokia 6610 display driver specification (Philips or Epson).
//
//*****************************************************************************
//#define DRIVER_PHILIPS
#define DRIVER_EPSON
 
//*****************************************************************************
//
// Prototypes for the globals exported by this driver.
//
//*****************************************************************************
extern void Nokia6610Init(unsigned long ulFrequency);
extern void Nokia6610Backlight(tBoolean bState);
extern const tDisplay g_sNokia6610;
 
#endif // __NOKIA_6610_H__