This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revision | |||
| en:software:arm-can:drivers:nokia6610 [2010/02/23 15:12] – mikk.leini | en:software:arm-can:drivers:nokia6610 [2020/07/20 12:00] (current) – external edit 127.0.0.1 | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| + | ====== Nokia 6610 LCD driver ====== | ||
| + | Texas Instruments (Luminary Micro) StellarisWare Graphics Library driver for Nokia 6610 LCD display with backlight. | ||
| + | |||
| + | ===== nokia6610.c ===== | ||
| + | |||
| + | <code 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, | ||
| + | // DAMAGES, FOR ANY REASON WHATSOEVER. | ||
| + | // | ||
| + | // | ||
| + | |||
| + | // | ||
| + | // | ||
| + | //! \addtogroup display_api | ||
| + | //! @{ | ||
| + | // | ||
| + | // | ||
| + | |||
| + | #include " | ||
| + | #include " | ||
| + | #include " | ||
| + | #include " | ||
| + | #include " | ||
| + | #include " | ||
| + | #include " | ||
| + | #include " | ||
| + | #include " | ||
| + | #include " | ||
| + | #include " | ||
| + | #include " | ||
| + | |||
| + | // | ||
| + | // | ||
| + | // Macros that define the peripheral, port, and pin used for the OLEDDC | ||
| + | // panel control signal. | ||
| + | // | ||
| + | // | ||
| + | #define SYSCTL_PERIPH_GPIO_OLEDDC | ||
| + | #define GPIO_LCD_BASE | ||
| + | #define GPIO_LCD_RST_PIN | ||
| + | #define GPIO_LCD_BL_PIN | ||
| + | |||
| + | // | ||
| + | // | ||
| + | // Display configuration. | ||
| + | // | ||
| + | // | ||
| + | #define SCREEN_OFFSET_X | ||
| + | #define SCREEN_OFFSET_Y | ||
| + | #define SCREEN_WIDTH | ||
| + | #define SCREEN_HEIGHT | ||
| + | |||
| + | // | ||
| + | // | ||
| + | // | ||
| + | // | ||
| + | // | ||
| + | #ifdef DRIVER_PHILIPS | ||
| + | |||
| + | #define NOP | ||
| + | #define SOFTRST | ||
| + | #define BOOSTVOFF | ||
| + | #define BOOSTVON | ||
| + | #define TESTMODE1 | ||
| + | #define DISPSTATUS | ||
| + | #define SLEEPIN | ||
| + | #define SLEEPOUT | ||
| + | #define PARTIAL | ||
| + | #define NORMALMODE | ||
| + | #define INVERSIONOFF | ||
| + | #define INVERSIONON | ||
| + | #define ALLPIXELOFF | ||
| + | #define ALLPIXELON | ||
| + | #define CONTRAST | ||
| + | #define DISPLAYOFF | ||
| + | #define DISPLAYON | ||
| + | #define COLADDRSET | ||
| + | #define PAGEADDRSET | ||
| + | #define MEMWRITE | ||
| + | #define COLORSET | ||
| + | #define READRAMDATA | ||
| + | #define PARTIALAREA | ||
| + | #define VERTSCROLL | ||
| + | #define TESTMODE2 | ||
| + | #define TESTMODE3 | ||
| + | #define ACCESSCTRL | ||
| + | #define VSCRLSADDR | ||
| + | #define IDLEOFF | ||
| + | #define IDLEON | ||
| + | #define PIXELFORMAT | ||
| + | #define TESTMODE4 | ||
| + | #define NOP2 0xAA // nop | ||
| + | #define INITESC | ||
| + | #define TESTMODE5 | ||
| + | #define TESTMODE6 | ||
| + | #define TESTMODE7 | ||
| + | #define TESTMODE8 | ||
| + | #define GRAYSCALE0 | ||
| + | #define GRAYSCALE1 | ||
| + | #define GAMMA | ||
| + | #define DISPCTRL | ||
| + | #define TEMPGRADIENT | ||
| + | #define TESTMODE9 | ||
| + | #define REFSET | ||
| + | #define VOLTCTRL | ||
| + | #define COMMONDRV | ||
| + | #define PWRCTRL | ||
| + | |||
| + | #endif | ||
| + | |||
| + | |||
| + | // | ||
| + | // | ||
| + | // | ||
| + | // | ||
| + | // | ||
| + | #ifdef DRIVER_EPSON | ||
| + | |||
| + | #define DISON | ||
| + | #define DISOFF | ||
| + | #define DISNOR | ||
| + | #define DISINV | ||
| + | #define COMSCN | ||
| + | #define DISCTL | ||
| + | #define SLPIN | ||
| + | #define SLPOUT | ||
| + | #define PASET | ||
| + | #define CASET | ||
| + | #define DATCTL | ||
| + | #define RGBSET8 | ||
| + | #define RAMWR | ||
| + | #define RAMRD | ||
| + | #define PTLIN | ||
| + | #define PTLOUT | ||
| + | #define RMWIN | ||
| + | #define RMWOUT | ||
| + | #define ASCSET | ||
| + | #define SCSTART | ||
| + | #define OSCON | ||
| + | #define OSCOFF | ||
| + | #define PWRCTR | ||
| + | #define VOLCTR | ||
| + | #define VOLUP | ||
| + | #define VOLDOWN | ||
| + | #define TMPGRD | ||
| + | #define EPCTIN | ||
| + | #define EPCOUT | ||
| + | #define EPMWR | ||
| + | #define EPMRD | ||
| + | #define EPSRRD1 | ||
| + | #define EPSRRD2 | ||
| + | #define NOP | ||
| + | |||
| + | #endif | ||
| + | |||
| + | // | ||
| + | // | ||
| + | // Translates a 24-bit RGB color to a display driver-specific color. | ||
| + | // | ||
| + | // \param c is the 24-bit RGB color. | ||
| + | // 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' | ||
| + | // closest possible approximation of that color. | ||
| + | // | ||
| + | // \return Returns the display-driver specific color. | ||
| + | // | ||
| + | // | ||
| + | |||
| + | #define DPYCOLORTRANSLATE(c) | ||
| + | (((c) & 0x00F000) >> | ||
| + | (((c) & 0x0000F0) >> | ||
| + | |||
| + | // | ||
| + | // | ||
| + | //! \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, | ||
| + | |||
| + | // | ||
| + | // Dummy read to drain the FIFO and time the GPIO signal. | ||
| + | // | ||
| + | SSIDataGet(SSI0_BASE, | ||
| + | } | ||
| + | |||
| + | // | ||
| + | // | ||
| + | //! \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, | ||
| + | |||
| + | // | ||
| + | // Dummy read to drain the FIFO and time the GPIO signal. | ||
| + | // | ||
| + | SSIDataGet(SSI0_BASE, | ||
| + | } | ||
| + | |||
| + | // | ||
| + | // | ||
| + | //! 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, | ||
| + | GPIOPadConfigSet(GPIO_PORTA_BASE, | ||
| + | | ||
| + | |||
| + | // | ||
| + | // Configure the SSI0 port for master mode. | ||
| + | // | ||
| + | SSIConfigSetExpClk(SSI0_BASE, | ||
| + | | ||
| + | | ||
| + | // | ||
| + | // Enable the SSI port. | ||
| + | // | ||
| + | SSIEnable(SSI0_BASE); | ||
| + | |||
| + | // | ||
| + | // Drain the receive fifo. | ||
| + | // | ||
| + | while(SSIDataGetNonBlocking(SSI0_BASE, | ||
| + | { | ||
| + | } | ||
| + | |||
| + | // | ||
| + | // 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, | ||
| + | GPIOPadConfigSet(GPIO_LCD_BASE, | ||
| + | | ||
| + | GPIOPinWrite(GPIO_LCD_BASE, | ||
| + | |||
| + | // | ||
| + | // 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, | ||
| + | (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. | ||
| + | //! of the pixel are assumed to be within the extents of the display. | ||
| + | //! | ||
| + | //! \return None. | ||
| + | // | ||
| + | // | ||
| + | static void | ||
| + | Nokia6610PixelDraw(void *pvDisplayData, | ||
| + | | ||
| + | { | ||
| + | // | ||
| + | // 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. | ||
| + | //! 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 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 >> | ||
| + | | ||
| + | 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. " | ||
| + | // 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. | ||
| + | // http:// | ||
| + | // 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 line are assumed to be within the extents of the display. | ||
| + | //! | ||
| + | //! \return None. | ||
| + | // | ||
| + | // | ||
| + | static void | ||
| + | Nokia6610LineDrawH(void *pvDisplayData, | ||
| + | | ||
| + | { | ||
| + | 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. | ||
| + | //! line are assumed to be within the extents of the display. | ||
| + | //! | ||
| + | //! \return None. | ||
| + | // | ||
| + | // | ||
| + | static void | ||
| + | Nokia6610LineDrawV(void *pvDisplayData, | ||
| + | | ||
| + | { | ||
| + | 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. | ||
| + | //! 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, | ||
| + | unsigned long ulValue) | ||
| + | { | ||
| + | long lCount; | ||
| + | |||
| + | // | ||
| + | // Page column (X) set. | ||
| + | // | ||
| + | WriteCommand(CASET); | ||
| + | WriteData(pRect-> | ||
| + | WriteData(pRect-> | ||
| + | |||
| + | // | ||
| + | // Page address (Y) set. | ||
| + | // | ||
| + | WriteCommand(PASET); | ||
| + | WriteData(pRect-> | ||
| + | WriteData(pRect-> | ||
| + | |||
| + | // | ||
| + | // Write memory. | ||
| + | // | ||
| + | WriteCommand(RAMWR); | ||
| + | |||
| + | // | ||
| + | // Count number of pixel pairs + 1 | ||
| + | // | ||
| + | lCount = ((pRect-> | ||
| + | (pRect-> | ||
| + | |||
| + | // | ||
| + | // 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. | ||
| + | //! 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' | ||
| + | //! or the closest possible approximation of that color. | ||
| + | //! | ||
| + | //! \return Returns the display-driver specific color. | ||
| + | // | ||
| + | // | ||
| + | static unsigned long | ||
| + | Nokia6610ColorTranslate(void *pvDisplayData, | ||
| + | { | ||
| + | // | ||
| + | // 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. | ||
| + | //! is useful when a local frame buffer is used for drawing operations, and the | ||
| + | //! flush would copy the local frame buffer to the display. | ||
| + | //! 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 ===== | ||
| + | |||
| + | <code c> | ||
| + | // | ||
| + | // | ||
| + | // 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, | ||
| + | // 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__ | ||
| + | </ | ||