Skip to content
Browse files

Initial commit. Driver heavily modified for multiple instances and ea…

…se of porting (via templatization).
  • Loading branch information...
0 parents commit c6c103365699addb1375773dc821b06d994591f8 @AretCarlsen committed Jun 10, 2010
659 Philips_PCD8544.cpp
@@ -0,0 +1,659 @@
+/*
+ *
+ * Name : pcd8544.c
+ *
+ * Description : This is a driver for the PCD8544 graphic LCD.
+ * Based on the code written by Sylvain Bissonette
+ * This driver is buffered in 504 bytes memory be sure
+ * that your MCU having bigger memory
+ *
+ * Author : Fandi Gunawan <fandigunawan@gmail.com>
+ * Website : http://fandigunawan.wordpress.com
+ *
+ * Credit : Sylvain Bissonette (2003)
+ *
+ * License : GPL v. 3
+ *
+ * Compiler : avr-g++
+ *
+ * History :
+ * June 10, 2010: C++ port by Aret Carlsen
+ * + Replaced most #defines with static consts.
+ * + Templated for porting to various architectures and underlying hardware.
+ * Version 0.2.6 (March 14, 2009) additional optimization by Jakub Lasinski
+ * + Optimization using Memset and Memcpy
+ * + Bug fix and sample program reviewed
+ * + Commented <stdio.h>
+ * Version 0.2.5 (December 25, 2008) x-mas version :)
+ * + Boundary check is added (reported by starlino on Dec 20, 2008)
+ * + Return value is added, it will definitely useful for error checking
+ * Version 0.2.4 (March 5, 2008)
+ * + Multiplier was added to bars to scale the bars
+ * Version 0.2.3 (February 29, 2008)
+ * + Rolled back fStr function because of serious bug
+ * + Stable release
+ * Version 0.2.2 (February 27, 2008)
+ * + Optimizing fStr function
+ * Version 0.2.1 (January 2, 2008)
+ * + Clean up codes
+ * + All settings were migrated to pcd8544.h
+ * + Using _BV() instead of << to make a better readable code
+ * Version 0.2 (December 11-14, 2007)
+ * + Bug fixed in line() and str()
+ * + Adding new routine
+ * - fStr()
+ * - singleBar()
+ * - bars()
+ * - rect()
+ * - image()
+ * + PROGMEM used instead of using.data section
+ * Version 0.1 (December 3, 2007)
+ * + First stable driver
+ *
+ * Note :
+ * Font will be displayed this way (16x6)
+ * 1 2 3 4 5 6 7 8 9 0 1 2 3 4
+ * 2
+ * 3
+ * 4
+ * 5
+ * 6
+ *
+ * Contributor :
+ * + Jakub Lasinski
+ */
+
+/*
+#include <avr/io.h>
+#include <string.h>
+#include <avr/pgmspace.h>
+#include <avr/interrupt.h>
+*/
+
+/*
+ * Name : LcdInit
+ * Description : Performs MCU LCD controller initialization.
+ * Argument(s) : None.
+ * Return value : None.
+ */
+template<typename SPI_bus_t, typename LCD_DC_pin_t, typename LCD_CE_pin_t, typename LCD_RST_pin_t> void Philips_PCD8544<SPI_bus_t, LCD_DC_pin_t, LCD_CE_pin_t, LCD_RST_pin_t>::init ( void ) {
+/*
+ // Pull-up on reset pin.
+ LCD_RST_pin.enable_pullup();
+*/
+
+ Delay();
+
+ /* Toggle display reset pin. */
+ LCD_RST_pin.set_output_low();
+ Delay();
+ LCD_RST_pin.set_output_high();
+
+ /* Disable LCD controller */
+ LCD_CE_pin.set_output_high();
+
+ send( 0x21, LCD_CMD ); /* LCD Extended Commands. */
+ send( 0xC8, LCD_CMD ); /* Set LCD Vop (Contrast).*/
+ send( 0x06, LCD_CMD ); /* Set Temp coefficent. */
+ send( 0x13, LCD_CMD ); /* LCD bias mode 1:48. */
+ send( 0x20, LCD_CMD ); /* LCD Standard Commands,Horizontal addressing mode */
+ send( 0x0C, LCD_CMD ); /* LCD in normal mode. */
+
+ /* Reset watermark pointers to empty */
+ LoWaterMark = LCD_CACHE_SIZE;
+ HiWaterMark = 0;
+
+ /* Clear display on first time use */
+ clear();
+ update();
+}
+
+/*
+ * Name : LcdContrast
+ * Description : Set display contrast.
+ * Argument(s) : contrast -> Contrast value from 0x00 to 0x7F.
+ * Return value : None.
+ */
+template<typename SPI_bus_t, typename LCD_DC_pin_t, typename LCD_CE_pin_t, typename LCD_RST_pin_t> void Philips_PCD8544<SPI_bus_t, LCD_DC_pin_t, LCD_CE_pin_t, LCD_RST_pin_t>::contrast ( byte contrast ) {
+ /* LCD Extended Commands. */
+ send( 0x21, LCD_CMD );
+
+ /* Set LCD contrast level. */
+ send( 0x80 | contrast, LCD_CMD );
+
+ /* LCD Standard Commands, horizontal addressing mode. */
+ send( 0x20, LCD_CMD );
+}
+
+/*
+ * Name : clear
+ * Description : Clears the display. update must be called next.
+ * Argument(s) : None.
+ * Return value : None.
+ * Note : Based on Sylvain Bissonette's code
+ */
+template<typename SPI_bus_t, typename LCD_DC_pin_t, typename LCD_CE_pin_t, typename LCD_RST_pin_t> void Philips_PCD8544<SPI_bus_t, LCD_DC_pin_t, LCD_CE_pin_t, LCD_RST_pin_t>::clear ( void ) {
+// Removed in version 0.2.6, March 14 2009
+// Optimized by Jakub Lasinski
+// int i;
+//
+// /* Set 0x00 to all screenCache's contents */
+// for ( i = 0; i < LCD_CACHE_SIZE; i++ )
+// {
+// screenCache[ i ] = 0x00;
+// }
+ memset(screenCache,0x00,LCD_CACHE_SIZE); //Suggestion - its faster and its 10 bytes less in program mem
+ /* Reset watermark pointers to full */
+ LoWaterMark = 0;
+ HiWaterMark = LCD_CACHE_SIZE - 1;
+
+ /* Set update flag to be true */
+ updateActive = TRUE;
+}
+
+/*
+ * Name : gotoXYFont
+ * Description : Sets cursor location to xy location corresponding to basic
+ * font size.
+ * Argument(s) : x, y -> Coordinate for new cursor position. Range: 1,1 .. 14,6
+ * Return value : see return value in pcd8544.h
+ * Note : Based on Sylvain Bissonette's code
+ */
+template<typename SPI_bus_t, typename LCD_DC_pin_t, typename LCD_CE_pin_t, typename LCD_RST_pin_t> byte Philips_PCD8544<SPI_bus_t, LCD_DC_pin_t, LCD_CE_pin_t, LCD_RST_pin_t>::gotoXYFont ( byte x, byte y ) {
+ /* Boundary check, slow down the speed but will guarantee this code wont fail */
+ /* Version 0.2.5 - Fixed on Dec 25, 2008 (XMAS) */
+ if( x > MAX_X_FONT)
+ return OUT_OF_BORDER;
+ if( y > MAX_Y_FONT)
+ return OUT_OF_BORDER;
+ /* Calculate index. It is defined as address within 504 bytes memory */
+
+ CacheIdx = ( x - 1 ) * 6 + ( y - 1 ) * 84;
+ return OK;
+}
+
+/*
+ * Name : chr
+ * Description : Displays a character at current cursor location and
+ * increment cursor location.
+ * Argument(s) : size -> Font size. See enum in pcd8544.h.
+ * ch -> Character to write.
+ * Return value : see pcd8544.h about return value
+ */
+template<typename SPI_bus_t, typename LCD_DC_pin_t, typename LCD_CE_pin_t, typename LCD_RST_pin_t> byte Philips_PCD8544<SPI_bus_t, LCD_DC_pin_t, LCD_CE_pin_t, LCD_RST_pin_t>::chr ( LcdFontSize size, byte ch ) {
+ byte i, c;
+ byte b1, b2;
+ CacheIndex_t tmpIdx;
+
+ if ( CacheIdx < LoWaterMark ){
+ /* Update low marker. */
+ LoWaterMark = CacheIdx;
+ }
+
+ if ( (ch < 0x20) || (ch > 0x7b) ){
+ /* Convert to a printable character. */
+ ch = 92;
+ }
+
+ if ( size == FONT_1X ){
+ for ( i = 0; i < 5; i++ )
+ {
+ /* Copy lookup table from Flash ROM to screenCache */
+ screenCache[CacheIdx++] = get_font_byte(ch - 32, i) << 1;
+ }
+ }else if ( size == FONT_2X ){
+// Modified to eliminate signedness [ANC 2010-04-24]
+ if(CacheIdx < 84){
+ LoWaterMark = 0;
+ return OUT_OF_BORDER;
+ }
+
+ tmpIdx = CacheIdx - 84;
+
+ if ( tmpIdx < LoWaterMark )
+ LoWaterMark = tmpIdx;
+
+ for ( i = 0; i < 5; i++ )
+ {
+ /* Copy lookup table from Flash ROM to temporary c */
+ c = get_font_byte(ch - 32, i) << 1;
+ /* Enlarge image */
+ /* First part */
+ b1 = (c & 0x01) * 3;
+ b1 |= (c & 0x02) * 6;
+ b1 |= (c & 0x04) * 12;
+ b1 |= (c & 0x08) * 24;
+
+ c >>= 4;
+ /* Second part */
+ b2 = (c & 0x01) * 3;
+ b2 |= (c & 0x02) * 6;
+ b2 |= (c & 0x04) * 12;
+ b2 |= (c & 0x08) * 24;
+
+ /* Copy two parts into screenCache */
+ screenCache[tmpIdx++] = b1;
+ screenCache[tmpIdx++] = b1;
+ screenCache[tmpIdx + 82] = b2;
+ screenCache[tmpIdx + 83] = b2;
+ }
+
+ /* Update x cursor position. */
+ /* Version 0.2.5 - Possible bug fixed on Dec 25,2008 */
+ CacheIdx = (CacheIdx + 11) % LCD_CACHE_SIZE;
+ }
+
+ if ( CacheIdx > HiWaterMark ){
+ /* Update high marker. */
+ HiWaterMark = CacheIdx;
+ }
+
+ /* Horizontal gap between characters. */
+ /* Version 0.2.5 - Possible bug fixed on Dec 25,2008 */
+ screenCache[CacheIdx] = 0x00;
+ /* At index number LCD_CACHE_SIZE - 1, wrap to 0 */
+ if(CacheIdx == (LCD_CACHE_SIZE - 1) )
+ {
+ CacheIdx = 0;
+ return OK_WITH_WRAP;
+ }
+ /* Otherwise just increment the index */
+ CacheIdx++;
+ return OK;
+}
+
+/*
+ * Name : str
+ * Description : Displays a character at current cursor location and increment
+ * cursor location according to font size. This function is
+ * dedicated to print string laid in SRAM
+ * Argument(s) : size -> Font size. See enum.
+ * dataArray -> Array contained string of char to be written
+ * into screenCache.
+ * Return value : see return value on pcd8544.h
+ */
+template<typename SPI_bus_t, typename LCD_DC_pin_t, typename LCD_CE_pin_t, typename LCD_RST_pin_t> byte Philips_PCD8544<SPI_bus_t, LCD_DC_pin_t, LCD_CE_pin_t, LCD_RST_pin_t>::str ( LcdFontSize size, byte dataArray[] ) {
+ byte tmpIdx=0;
+ byte response;
+ while( dataArray[ tmpIdx ] != '\0' ){
+ /* Send char */
+ response = chr( size, dataArray[ tmpIdx ] );
+ /* Just in case OUT_OF_BORDER occured */
+ /* Dont worry if the signal == OK_WITH_WRAP, the string will
+ be wrapped to starting point */
+ if( response == OUT_OF_BORDER)
+ return OUT_OF_BORDER;
+ /* Increase index */
+ tmpIdx++;
+ }
+ return OK;
+}
+
+/*
+ * Name : fStr
+ * Description : Displays a characters at current cursor location and increment
+ * cursor location according to font size. This function is
+ * dedicated to print string laid in Flash ROM
+ * Argument(s) : size -> Font size. See enum.
+ * dataPtr -> Pointer contained string of char to be written
+ * into screenCache.
+ * Return value : see return value on pcd8544.h
+ * Example : fStr(FONT_1X, PSTR("Hello World"));
+ * fStr(FONT_1X, &name_of_string_as_array);
+ */
+template<typename SPI_bus_t, typename LCD_DC_pin_t, typename LCD_CE_pin_t, typename LCD_RST_pin_t> byte Philips_PCD8544<SPI_bus_t, LCD_DC_pin_t, LCD_CE_pin_t, LCD_RST_pin_t>::fStr ( LcdFontSize size, const byte *dataPtr ) {
+ byte c;
+ byte response;
+ for ( c = pgm_read_byte( dataPtr ); c; ++dataPtr, c = pgm_read_byte( dataPtr ) )
+ {
+ /* Put char */
+ response = chr( size, c );
+ if(response == OUT_OF_BORDER)
+ return OUT_OF_BORDER;
+ }
+ /* Fixed by Jakub Lasinski. Version 0.2.6, March 14, 2009 */
+ return OK;
+}
+
+/*
+ * Name : pixel
+ * Description : Displays a pixel at given absolute (x, y) location.
+ * Argument(s) : x, y -> Absolute pixel coordinates
+ * mode -> Off, On or Xor. See enum in pcd8544.h.
+ * Return value : see return value on pcd8544.h
+ * Note : Based on Sylvain Bissonette's code
+ */
+template<typename SPI_bus_t, typename LCD_DC_pin_t, typename LCD_CE_pin_t, typename LCD_RST_pin_t> byte Philips_PCD8544<SPI_bus_t, LCD_DC_pin_t, LCD_CE_pin_t, LCD_RST_pin_t>::pixel ( byte x, byte y, PixelMode mode ) {
+ CacheIndex_t index;
+ byte offset;
+ byte data;
+
+ /* Prevent from getting out of border */
+ if ( x > LCD_X_RES ) return OUT_OF_BORDER;
+ if ( y > LCD_Y_RES ) return OUT_OF_BORDER;
+
+ /* Recalculating index and offset */
+ index = ( ( y / 8 ) * 84 ) + x;
+ offset = y - ( ( y / 8 ) * 8 );
+
+ data = screenCache[ index ];
+
+ /* Bit processing */
+
+ /* Clear mode */
+ if ( mode == PIXEL_OFF )
+ data &= ( ~( 0x01 << offset ) );
+
+ /* On mode */
+ else if ( mode == PIXEL_ON )
+ data |= ( 0x01 << offset );
+
+ /* Xor mode */
+ else if ( mode == PIXEL_XOR )
+ data ^= ( 0x01 << offset );
+
+ /* Final result copied to screenCache */
+ screenCache[ index ] = data;
+
+ if ( index < LoWaterMark )
+ /* Update low marker. */
+ LoWaterMark = index;
+
+ if ( index > HiWaterMark )
+ /* Update high marker. */
+ HiWaterMark = index;
+
+ return OK;
+}
+
+/*
+ * Name : line
+ * Description : Draws a line between two points on the display.
+ * Argument(s) : x1, y1 -> Absolute pixel coordinates for line origin.
+ * x2, y2 -> Absolute pixel coordinates for line end.
+ * mode -> Off, On or Xor. See enum in pcd8544.h.
+ * Return value : see return value on pcd8544.h
+ */
+template<typename SPI_bus_t, typename LCD_DC_pin_t, typename LCD_CE_pin_t, typename LCD_RST_pin_t> byte Philips_PCD8544<SPI_bus_t, LCD_DC_pin_t, LCD_CE_pin_t, LCD_RST_pin_t>::line ( byte x1, byte x2, byte y1, byte y2, PixelMode mode ) {
+ int dx, dy, stepx, stepy, fraction;
+ byte response;
+
+ /* Calculate differential form */
+ /* dy y2 - y1 */
+ /* -- = ------- */
+ /* dx x2 - x1 */
+
+ /* Take differences */
+ dy = y2 - y1;
+ dx = x2 - x1;
+
+ /* dy is negative */
+ if ( dy < 0 )
+ {
+ dy = -dy;
+ stepy = -1;
+ }
+ else
+ {
+ stepy = 1;
+ }
+
+ /* dx is negative */
+ if ( dx < 0 )
+ {
+ dx = -dx;
+ stepx = -1;
+ }
+ else
+ {
+ stepx = 1;
+ }
+
+ dx <<= 1;
+ dy <<= 1;
+
+ /* Draw initial position */
+ response = pixel( x1, y1, mode );
+ if(response)
+ return response;
+
+ /* Draw next positions until end */
+ if ( dx > dy )
+ {
+ /* Take fraction */
+ fraction = dy - ( dx >> 1);
+ while ( x1 != x2 )
+ {
+ if ( fraction >= 0 )
+ {
+ y1 += stepy;
+ fraction -= dx;
+ }
+ x1 += stepx;
+ fraction += dy;
+
+ /* Draw calculated point */
+ response = pixel( x1, y1, mode );
+ if(response)
+ return response;
+
+ }
+ }
+ else
+ {
+ /* Take fraction */
+ fraction = dx - ( dy >> 1);
+ while ( y1 != y2 )
+ {
+ if ( fraction >= 0 )
+ {
+ x1 += stepx;
+ fraction -= dy;
+ }
+ y1 += stepy;
+ fraction += dx;
+
+ /* Draw calculated point */
+ response = pixel( x1, y1, mode );
+ if(response)
+ return response;
+ }
+ }
+
+ /* Set update flag to be true */
+ updateActive = TRUE;
+ return OK;
+}
+
+/*
+ * Name : singleBar
+ * Description : Display single bar.
+ * Argument(s) : baseX -> absolute x axis coordinate
+ * baseY -> absolute y axis coordinate
+ * height -> height of bar (in pixel)
+ * width -> width of bar (in pixel)
+ * mode -> Off, On or Xor. See enum in pcd8544.h.
+ * Return value : see return value on pcd8544.h
+ */
+template<typename SPI_bus_t, typename LCD_DC_pin_t, typename LCD_CE_pin_t, typename LCD_RST_pin_t> byte Philips_PCD8544<SPI_bus_t, LCD_DC_pin_t, LCD_CE_pin_t, LCD_RST_pin_t>::singleBar ( byte baseX, byte baseY, byte height, byte width, PixelMode mode ) {
+ byte tmpIdxX,tmpIdxY,tmp;
+
+ byte response;
+
+ /* Checking border */
+ if ( ( baseX > LCD_X_RES ) || ( baseY > LCD_Y_RES ) ) return OUT_OF_BORDER;
+
+ if ( height > baseY )
+ tmp = 0;
+ else
+ tmp = baseY - height;
+
+ /* Draw lines */
+ for ( tmpIdxY = tmp; tmpIdxY < baseY; tmpIdxY++ )
+ {
+ for ( tmpIdxX = baseX; tmpIdxX < (baseX + width); tmpIdxX++ )
+ {
+ response = pixel( tmpIdxX, tmpIdxY, mode );
+ if(response)
+ return response;
+
+ }
+ }
+
+ /* Set update flag to be true */
+ updateActive = TRUE;
+ return OK;
+}
+
+/*
+ * Name : bars
+ * Description : Display multiple bars.
+ * Argument(s) : data[] -> data which want to be plotted
+ * numbBars -> number of bars want to be plotted
+ * width -> width of bar (in pixel)
+ * Return value : see return value on pcd8544.h
+ * Note : Please check EMPTY_SPACE_BARS, BAR_X, BAR_Y in pcd8544.h
+ */
+template<typename SPI_bus_t, typename LCD_DC_pin_t, typename LCD_CE_pin_t, typename LCD_RST_pin_t> byte Philips_PCD8544<SPI_bus_t, LCD_DC_pin_t, LCD_CE_pin_t, LCD_RST_pin_t>::bars ( byte data[], byte numbBars, byte width, byte multiplier ) {
+ byte b;
+ byte tmpIdx = 0;
+ byte response;
+
+ for ( b = 0; b < numbBars ; b++ )
+ {
+ /* Preventing from out of border (LCD_X_RES) */
+ if ( tmpIdx > LCD_X_RES ) return OUT_OF_BORDER;
+
+ /* Calculate x axis */
+ tmpIdx = ((width + EMPTY_SPACE_BARS) * b) + BAR_X;
+
+ /* Draw single bar */
+ response = singleBar( tmpIdx, BAR_Y, data[ b ] * multiplier, width, PIXEL_ON);
+ if(response == OUT_OF_BORDER)
+ return response;
+ }
+
+ /* Set update flag to be true */
+ updateActive = TRUE;
+ return OK;
+
+}
+/*
+ * Name : rect
+ * Description : Display a rectangle.
+ * Argument(s) : x1 -> absolute first x axis coordinate
+ * y1 -> absolute first y axis coordinate
+ * x2 -> absolute second x axis coordinate
+ * y2 -> absolute second y axis coordinate
+ * mode -> Off, On or Xor. See enum in pcd8544.h.
+ * Return value : see return value on pcd8544.h.
+ */
+template<typename SPI_bus_t, typename LCD_DC_pin_t, typename LCD_CE_pin_t, typename LCD_RST_pin_t> byte Philips_PCD8544<SPI_bus_t, LCD_DC_pin_t, LCD_CE_pin_t, LCD_RST_pin_t>::rect ( byte x1, byte x2, byte y1, byte y2, PixelMode mode ) {
+ byte tmpIdxX,tmpIdxY;
+ byte response;
+
+ /* Checking border */
+ if ( ( x1 > LCD_X_RES ) || ( x2 > LCD_X_RES ) || ( y1 > LCD_Y_RES ) || ( y2 > LCD_Y_RES ) )
+ /* If out of border then return */
+ return OUT_OF_BORDER;
+
+ if ( ( x2 > x1 ) && ( y2 > y1 ) )
+ {
+ for ( tmpIdxY = y1; tmpIdxY < y2; tmpIdxY++ )
+ {
+ /* Draw line horizontally */
+ for ( tmpIdxX = x1; tmpIdxX < x2; tmpIdxX++ )
+ {
+ /* Draw a pixel */
+ response = pixel( tmpIdxX, tmpIdxY, mode );
+ if(response)
+ return response;
+ }
+ }
+
+ /* Set update flag to be true */
+ updateActive = TRUE;
+ }
+ return OK;
+}
+/*
+ * Name : image
+ * Description : Image mode display routine.
+ * Argument(s) : Address of image in hexes
+ * Return value : None.
+ * Example : image(&sample_image_declared_as_array);
+ */
+template<typename SPI_bus_t, typename LCD_DC_pin_t, typename LCD_CE_pin_t, typename LCD_RST_pin_t> void Philips_PCD8544<SPI_bus_t, LCD_DC_pin_t, LCD_CE_pin_t, LCD_RST_pin_t>::image ( const byte *imageData ) {
+ /* Initialize screenCache index to 0 */
+// CacheIdx = 0;
+// /* While within screenCache range */
+// for ( CacheIdx = 0; CacheIdx < LCD_CACHE_SIZE; CacheIdx++ )
+// {
+// /* Copy data from pointer to screenCache buffer */
+// screenCache[CacheIdx] = pgm_read_byte( imageData++ );
+// }
+ /* optimized by Jakub Lasinski, version 0.2.6, March 14, 2009 */
+ memcpy_P(screenCache,imageData,LCD_CACHE_SIZE); //Same as aboeve - 6 bytes less and faster instruction
+ /* Reset watermark pointers to be full */
+ LoWaterMark = 0;
+ HiWaterMark = LCD_CACHE_SIZE - 1;
+
+ /* Set update flag to be true */
+ updateActive = TRUE;
+}
+
+/*
+ * Name : update
+ * Description : Copies the LCD screenCache into the device RAM.
+ * Argument(s) : None.
+ * Return value : None.
+ */
+template<typename SPI_bus_t, typename LCD_DC_pin_t, typename LCD_CE_pin_t, typename LCD_RST_pin_t> void Philips_PCD8544<SPI_bus_t, LCD_DC_pin_t, LCD_CE_pin_t, LCD_RST_pin_t>::update ( void ) {
+ CacheIndex_t i;
+
+ if ( LoWaterMark >= LCD_CACHE_SIZE )
+ LoWaterMark = LCD_CACHE_SIZE - 1;
+
+ if ( HiWaterMark >= LCD_CACHE_SIZE )
+ HiWaterMark = LCD_CACHE_SIZE - 1;
+
+ /* Set base address according to LoWaterMark. */
+ send( 0x80 | ( LoWaterMark % LCD_X_RES ), LCD_CMD );
+ send( 0x40 | ( LoWaterMark / LCD_X_RES ), LCD_CMD );
+
+ /* Serialize the display buffer. */
+ for ( i = LoWaterMark; i <= HiWaterMark; i++ )
+ send( screenCache[ i ], LCD_DATA );
+
+ /* Reset watermark pointers. */
+ LoWaterMark = LCD_CACHE_SIZE - 1;
+ HiWaterMark = 0;
+
+ /* Set update flag to be true */
+ updateActive = FALSE;
+}
+
+/*
+ * Name : send
+ * Description : Sends data to display controller.
+ * Argument(s) : data -> Data to be sent
+ * cd -> Command or data (see enum in pcd8544.h)
+ * Return value : None.
+ */
+// Was static
+template<typename SPI_bus_t, typename LCD_DC_pin_t, typename LCD_CE_pin_t, typename LCD_RST_pin_t> void Philips_PCD8544<SPI_bus_t, LCD_DC_pin_t, LCD_CE_pin_t, LCD_RST_pin_t>::send ( byte data, LcdCmdData cd ) {
+ /* Enable display controller (active low). */
+ LCD_CE_pin.set_output_low();
+
+ if ( cd == LCD_DATA )
+ LCD_DC_pin.set_output_high();
+ else
+ LCD_DC_pin.set_output_low();
+
+ /* Send data to display controller. */
+ SPI_bus.transceive(data);
+
+ /* Disable display controller. */
+ LCD_CE_pin.set_output_high();
+}
+
135 Philips_PCD8544.hpp
@@ -0,0 +1,135 @@
+/*
+ *
+ * Name : pcd8544.h
+ *
+ * Description : This is header file for the PCD8544 graphic LCD driver.
+ * Based on the code written by Sylvain Bissonette
+ *
+ * Author : Fandi Gunawan <fandigunawan@gmail.com>
+ * Website : http://fandigunawan.wordpress.com
+ *
+ * Credit : Sylvain Bissonette (2003)
+ * Louis Frigon (2003)
+ * Other people (2010)
+ *
+ * License : GPL v. 3
+ *
+ * Compiler : WinAVR, GCC for AVR platform
+ * Tested version :
+ * - 20070525
+ * - 20071221
+ * - 20081225
+ * Compiler note: Please be aware of using older/newer version since WinAVR
+ * is in extensive development. Please compile with parameter -O1
+ *
+ * History :
+ * Please refer to pcd8544.c
+ */
+
+#pragma once
+
+#include <ATcommon/arch/avr/avr.hpp>
+
+namespace Philips_PCD8544 {
+
+/* For return value */
+static const uint8_t OK = 0;
+static const uint8_t OUT_OF_BORDER = 1;
+static const uint8_t OK_WITH_WRAP = 2;
+
+static const uint8_t LCD_X_RES = 84; /* x resolution */
+static const uint8_t LCD_Y_RES = 48; /* y resolution */
+static const uint8_t EMPTY_SPACE_BARS = 2;
+static const uint8_t BAR_X = 5;
+static const uint8_t BAR_Y = 38;
+
+static const uint8_t MAX_X_FONT = LCD_X_RES / 6;
+static const uint8_t MAX_Y_FONT = LCD_Y_RES / 8;
+
+/* Cache size in bytes ( 84 * 48 ) / 8 = 504 bytes */
+static const uint16_t LCD_CACHE_SIZE = ( LCD_X_RES * LCD_Y_RES ) / 8;
+
+/* Type definition */
+typedef uint8_t byte;
+
+// Modified by ANC 2010-04-24 (to eliminate signedness). (Was a signed int.)
+typedef uint16_t CacheIndex_t;
+
+/* Enumeration */
+typedef enum {
+ LCD_CMD = 0,
+ LCD_DATA = 1
+} LcdCmdData;
+
+typedef enum {
+ PIXEL_OFF = 0,
+ PIXEL_ON = 1,
+ PIXEL_XOR = 2
+} PixelMode;
+
+typedef enum {
+ FONT_1X = 1,
+ FONT_2X = 2
+} LcdFontSize;
+
+uint8_t get_font_byte(uint8_t x, uint8_t y);
+
+// Architecture-specific delay routine.
+static void Delay ( void );
+
+template <typename SPI_bus_t, typename LCD_DC_pin_t, typename LCD_CE_pin_t, typename LCD_RST_pin_t>
+class Philips_PCD8544 {
+private:
+// Architecture-specific hardware.
+ SPI_bus_t SPI_bus;
+ LCD_DC_pin_t LCD_DC_pin;
+ LCD_CE_pin_t LCD_CE_pin;
+ LCD_RST_pin_t LCD_RST_pin;
+
+/* Cache buffer in SRAM 84*48 bits or 504 bytes */
+ byte screenCache[ LCD_CACHE_SIZE ];
+
+// Modified to eliminate signedness [ANC 2010-04-24]
+/* Cache index */
+ CacheIndex_t CacheIdx;
+/* Lower part of water mark */
+ CacheIndex_t LoWaterMark;
+/* Higher part of water mark */
+ CacheIndex_t HiWaterMark;
+
+/* Variable to decide whether update Lcd Cache is active/nonactive */
+ bool updateActive;
+
+
+public:
+ Philips_PCD8544(SPI_bus_t &new_SPI_bus, LCD_DC_pin_t &new_LCD_DC_pin, LCD_CE_pin_t &new_LCD_CE_pin, LCD_RST_pin_t &new_LCD_RST_pin)
+ : SPI_bus(new_SPI_bus), LCD_DC_pin(new_LCD_DC_pin), LCD_CE_pin(new_LCD_CE_pin), LCD_RST_pin(new_LCD_RST_pin)
+ { }
+// When the pin and SPI bus objects are stateless, use this constructor.
+ Philips_PCD8544()
+ { }
+
+/* Function prototypes */
+ void send ( byte data, LcdCmdData cd );
+ void init ( void );
+ void clear ( void );
+ void update ( void );
+ void image ( const byte *imageData );
+ void contrast ( byte contrast );
+ byte gotoXYFont ( byte x, byte y );
+ byte chr ( LcdFontSize size, byte ch );
+ byte str ( LcdFontSize size, byte dataArray[] );
+ byte fStr ( LcdFontSize size, const byte *dataPtr );
+ byte pixel ( byte x, byte y, PixelMode mode );
+ byte line ( byte x1, byte x2, byte y1, byte y2, PixelMode mode );
+ byte rect ( byte x1, byte x2, byte y1, byte y2, PixelMode mode );
+ byte singleBar ( byte baseX, byte baseY, byte height, byte width, PixelMode mode );
+ byte bars ( byte data[], byte numbBars, byte width, byte multiplier );
+};
+
+// Inline for templates
+#include "Philips_PCD8544.cpp"
+
+// End namespace: Philips_PCD8544
+}
+
80 Philips_PCD8544_Server.hpp
@@ -0,0 +1,80 @@
+#pragma once
+
+#include "Philips_PCD8544.hpp"
+#include <Upacket/Servers/SimpleServer.hpp>
+
+#ifndef DEBUGprint_MISC
+#define DEBUGprint_MISC(...)
+#endif
+
+namespace Philips_PCD8544{
+
+template <typename LCD_t>
+class StringLCDServer : public SimpleServer, public Process {
+ LCD_t *lcd;
+
+public:
+ StringLCDServer(LCD_t *new_lcd)
+ : lcd(new_lcd)
+ { }
+
+Status::Status_t process(){
+ // Packet to process?
+ if(! packetPending()) return Status::Status__Good;
+
+ DEBUGprint_MISC("SLS: Prc pk\n");
+
+ // Data in packet?
+ MAP::Data_t *data_ptr = offsetPacket.packet->get_data(offsetPacket.headerOffset);
+ if(data_ptr == NULL) return finishedWithPacket();
+
+ // Clear screen
+ lcd->clear();
+
+ // Write packet contents out to screen, beginning at first row and performing a linefeed
+ // when the right edge of the screen is encountered.
+ for(uint8_t Y = 1; Y <= MAX_Y_FONT; Y++){
+ // Start at leftmost edge of screen
+ lcd->gotoXYFont(1,Y);
+ while(data_ptr < offsetPacket.packet->back()){
+ uint8_t response = lcd->chr(FONT_1X, *data_ptr);
+ if(response != OK){
+ // If wrapped, the character has actually been written.
+ if(response == OK_WITH_WRAP) data_ptr++;
+ // Move to next line
+ break;
+ }
+ // Move to next character
+ data_ptr++;
+ }
+ }
+
+ // Update screen
+ lcd->update();
+
+ return finishedWithPacket();
+}
+};
+
+/*
+class GalvLCDServer : public SimpleServer {
+ process(){
+ // Packet to process?
+ if(! packetPending()) return;
+
+ // Data in packet?
+ int32_t raw_value;
+ if(! packet->sourceC78Signed(raw_value, packet->get_data())) return;
+ FixedPoint<uint16_t, 14> value(raw_value, true);
+
+ // Display galvanometer
+ LCDClear();
+ LCDGalvDisplay(value);
+ LCDUpdate();
+ }
+};
+*/
+
+// End namespace: Philips_PCD8544
+}
+
3 arch/avr/Philips_PCD8544.cpp
@@ -0,0 +1,3 @@
+
+#include "../../Philips_PCD8544.cpp"
+
5 arch/avr/Philips_PCD8544.hpp
@@ -0,0 +1,5 @@
+
+#include <ATcommon/arch/avr/avr.hpp>
+#include "time.hpp"
+#include "../../Philips_PCD8544.hpp"
+
1 arch/avr/Philips_PCD8544_Server.hpp
18 arch/avr/sbFont.cpp
@@ -0,0 +1,18 @@
+
+// AVR architecture font retrieval.
+
+#include <ATcommon/arch/avr/avr.hpp>
+
+namespace Philips_PCD8544 {
+
+// This table defines the standard ASCII characters in a 5x7 dot format.
+const uint8_t FontLookup [91][5] PROGMEM =
+#include "../../sbFont.hpp"
+
+uint8_t get_font_byte(uint8_t x, uint8_t y){
+ return pgm_read_byte(&( FontLookup[x][y] ) );
+}
+
+// End namespace: Philips_PCD8544
+};
+
18 arch/avr/time.hpp
@@ -0,0 +1,18 @@
+
+#pragma once
+
+namespace Philips_PCD8544 {
+
+/*
+ * Name : Delay
+ * Description : Uncalibrated delay for LCD init routine.
+ * Argument(s) : None.
+ * Return value : None.
+ */
+inline static void Delay ( void ) {
+ for ( int16_t i = -32000; i < 32000; i++ ) nop();
+}
+
+// End namespace: Philips_PCD8544
+}
+
99 sbFont.hpp
@@ -0,0 +1,99 @@
+
+/*
+ * Character lookup table code was taken from the work of Sylvain Bissonette
+ * This table defines the standard ASCII characters in a 5x7 dot format.
+ */
+{
+ { 0x00, 0x00, 0x00, 0x00, 0x00 }, /* space */
+ { 0x00, 0x00, 0x2f, 0x00, 0x00 }, /* ! */
+ { 0x00, 0x07, 0x00, 0x07, 0x00 }, /* " */
+ { 0x14, 0x7f, 0x14, 0x7f, 0x14 }, /* # */
+ { 0x24, 0x2a, 0x7f, 0x2a, 0x12 }, /* $ */
+ { 0xc4, 0xc8, 0x10, 0x26, 0x46 }, /* % */
+ { 0x36, 0x49, 0x55, 0x22, 0x50 }, /* & */
+ { 0x00, 0x05, 0x03, 0x00, 0x00 }, /* ' */
+ { 0x00, 0x1c, 0x22, 0x41, 0x00 }, /* ( */
+ { 0x00, 0x41, 0x22, 0x1c, 0x00 }, /* ) */
+ { 0x14, 0x08, 0x3E, 0x08, 0x14 }, /* * */
+ { 0x08, 0x08, 0x3E, 0x08, 0x08 }, /* + */
+ { 0x00, 0x00, 0x50, 0x30, 0x00 }, /* , */
+ { 0x10, 0x10, 0x10, 0x10, 0x10 }, /* - */
+ { 0x00, 0x60, 0x60, 0x00, 0x00 }, /* . */
+ { 0x20, 0x10, 0x08, 0x04, 0x02 }, /* / */
+ { 0x3E, 0x51, 0x49, 0x45, 0x3E }, /* 0 */
+ { 0x00, 0x42, 0x7F, 0x40, 0x00 }, /* 1 */
+ { 0x42, 0x61, 0x51, 0x49, 0x46 }, /* 2 */
+ { 0x21, 0x41, 0x45, 0x4B, 0x31 }, /* 3 */
+ { 0x18, 0x14, 0x12, 0x7F, 0x10 }, /* 4 */
+ { 0x27, 0x45, 0x45, 0x45, 0x39 }, /* 5 */
+ { 0x3C, 0x4A, 0x49, 0x49, 0x30 }, /* 6 */
+ { 0x01, 0x71, 0x09, 0x05, 0x03 }, /* 7 */
+ { 0x36, 0x49, 0x49, 0x49, 0x36 }, /* 8 */
+ { 0x06, 0x49, 0x49, 0x29, 0x1E }, /* 9 */
+ { 0x00, 0x36, 0x36, 0x00, 0x00 }, /* : */
+ { 0x00, 0x56, 0x36, 0x00, 0x00 }, /* ; */
+ { 0x08, 0x14, 0x22, 0x41, 0x00 }, /* < */
+ { 0x14, 0x14, 0x14, 0x14, 0x14 }, /* = */
+ { 0x00, 0x41, 0x22, 0x14, 0x08 }, /* > */
+ { 0x02, 0x01, 0x51, 0x09, 0x06 }, /* ? */
+ { 0x32, 0x49, 0x59, 0x51, 0x3E }, /* @ */
+ { 0x7E, 0x11, 0x11, 0x11, 0x7E }, /* A */
+ { 0x7F, 0x49, 0x49, 0x49, 0x36 }, /* B */
+ { 0x3E, 0x41, 0x41, 0x41, 0x22 }, /* C */
+ { 0x7F, 0x41, 0x41, 0x22, 0x1C }, /* D */
+ { 0x7F, 0x49, 0x49, 0x49, 0x41 }, /* E */
+ { 0x7F, 0x09, 0x09, 0x09, 0x01 }, /* F */
+ { 0x3E, 0x41, 0x49, 0x49, 0x7A }, /* G */
+ { 0x7F, 0x08, 0x08, 0x08, 0x7F }, /* H */
+ { 0x00, 0x41, 0x7F, 0x41, 0x00 }, /* I */
+ { 0x20, 0x40, 0x41, 0x3F, 0x01 }, /* J */
+ { 0x7F, 0x08, 0x14, 0x22, 0x41 }, /* K */
+ { 0x7F, 0x40, 0x40, 0x40, 0x40 }, /* L */
+ { 0x7F, 0x02, 0x0C, 0x02, 0x7F }, /* M */
+ { 0x7F, 0x04, 0x08, 0x10, 0x7F }, /* N */
+ { 0x3E, 0x41, 0x41, 0x41, 0x3E }, /* O */
+ { 0x7F, 0x09, 0x09, 0x09, 0x06 }, /* P */
+ { 0x3E, 0x41, 0x51, 0x21, 0x5E }, /* Q */
+ { 0x7F, 0x09, 0x19, 0x29, 0x46 }, /* R */
+ { 0x46, 0x49, 0x49, 0x49, 0x31 }, /* S */
+ { 0x01, 0x01, 0x7F, 0x01, 0x01 }, /* T */
+ { 0x3F, 0x40, 0x40, 0x40, 0x3F }, /* U */
+ { 0x1F, 0x20, 0x40, 0x20, 0x1F }, /* V */
+ { 0x3F, 0x40, 0x38, 0x40, 0x3F }, /* W */
+ { 0x63, 0x14, 0x08, 0x14, 0x63 }, /* X */
+ { 0x07, 0x08, 0x70, 0x08, 0x07 }, /* Y */
+ { 0x61, 0x51, 0x49, 0x45, 0x43 }, /* Z */
+ { 0x00, 0x7F, 0x41, 0x41, 0x00 }, /* [ */
+ { 0x55, 0x2A, 0x55, 0x2A, 0x55 }, /* "Yen" */
+ { 0x00, 0x41, 0x41, 0x7F, 0x00 }, /* ] */
+ { 0x04, 0x02, 0x01, 0x02, 0x04 }, /* ^ */
+ { 0x40, 0x40, 0x40, 0x40, 0x40 }, /* _ */
+ { 0x00, 0x01, 0x02, 0x04, 0x00 }, /* ' */
+ { 0x20, 0x54, 0x54, 0x54, 0x78 }, /* a */
+ { 0x7F, 0x48, 0x44, 0x44, 0x38 }, /* b */
+ { 0x38, 0x44, 0x44, 0x44, 0x20 }, /* c */
+ { 0x38, 0x44, 0x44, 0x48, 0x7F }, /* d */
+ { 0x38, 0x54, 0x54, 0x54, 0x18 }, /* e */
+ { 0x08, 0x7E, 0x09, 0x01, 0x02 }, /* f */
+ { 0x0C, 0x52, 0x52, 0x52, 0x3E }, /* g */
+ { 0x7F, 0x08, 0x04, 0x04, 0x78 }, /* h */
+ { 0x00, 0x44, 0x7D, 0x40, 0x00 }, /* i */
+ { 0x20, 0x40, 0x44, 0x3D, 0x00 }, /* j */
+ { 0x7F, 0x10, 0x28, 0x44, 0x00 }, /* k */
+ { 0x00, 0x41, 0x7F, 0x40, 0x00 }, /* l */
+ { 0x7C, 0x04, 0x18, 0x04, 0x78 }, /* m */
+ { 0x7C, 0x08, 0x04, 0x04, 0x78 }, /* n */
+ { 0x38, 0x44, 0x44, 0x44, 0x38 }, /* o */
+ { 0x7C, 0x14, 0x14, 0x14, 0x08 }, /* p */
+ { 0x08, 0x14, 0x14, 0x18, 0x7C }, /* q */
+ { 0x7C, 0x08, 0x04, 0x04, 0x08 }, /* r */
+ { 0x48, 0x54, 0x54, 0x54, 0x20 }, /* s */
+ { 0x04, 0x3F, 0x44, 0x40, 0x20 }, /* t */
+ { 0x3C, 0x40, 0x40, 0x20, 0x7C }, /* u */
+ { 0x1C, 0x20, 0x40, 0x20, 0x1C }, /* v */
+ { 0x3C, 0x40, 0x30, 0x40, 0x3C }, /* w */
+ { 0x44, 0x28, 0x10, 0x28, 0x44 }, /* x */
+ { 0x0C, 0x50, 0x50, 0x50, 0x3C }, /* y */
+ { 0x44, 0x64, 0x54, 0x4C, 0x44 } /* z */
+};
+

0 comments on commit c6c1033

Please sign in to comment.
Something went wrong with that request. Please try again.