00001 00002 00003 /* This class was modified by Laurent Itti from the following. 00004 Modifications include: 00005 - timing to work on a 16MHz arduino 00006 - new bargraph graphics 00007 - fix code throughout so that when a width and height are used, they 00008 are the actual drawn width and height (as opposed to width-1 and 00009 height-1). So FillRect(0, 0, 128, 164, BLACK) fills the entire 00010 128x64 screen. 00011 */ 00012 00013 00014 /* 00015 ks0108.h - Arduino library support for ks0108 and compatable graphic LCDs 00016 Copyright (c)2008 Michael Margolis All right reserved 00017 mailto:memargolis@hotmail.com?subject=KS0108_Library 00018 00019 This library is based on version 1.1 of the excellent ks0108 graphics routines written and 00020 copyright by Fabian Maximilian Thiele. His sitelink is 00021 dead but you can obtain a copy of his original work here: 00022 http://www.scienceprog.com/wp-content/uploads/2007/07/glcd_ks0108.zip 00023 00024 Code changes include conversion to an Arduino C++ library, adding more 00025 flexibility in port addressing and improvements in I/O speed. The interface 00026 has been made more Arduino friendly and some convenience functions added. 00027 00028 This library is distributed in the hope that it will be useful, 00029 but WITHOUT ANY WARRANTY; without even the implied warranty of 00030 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00031 00032 Version: 1.0 - May 8 2008 - initial release 00033 Version: 1.0a - Sept 1 2008 - simplified command pin defines 00034 Version: 1.0b - Sept 18 2008 - replaced <wiring.h> with boolean typedef for rel 0012 00035 */ 00036 00037 #include <inttypes.h> 00038 //#include <wiring.h> // for boolean 00039 typedef uint8_t boolean; 00040 typedef uint8_t byte; 00041 #include <avr/pgmspace.h> 00042 00043 #ifndef KS0108ILAB_H 00044 #define KS0108ILAB_H 00045 00046 /*********************************************************/ 00047 /* Configuration for assigning LCD bits to Arduino Pins */ 00048 /*********************************************************/ 00049 /* Arduino pins used for Commands 00050 * default assignment uses the first five analog pins 00051 */ 00052 00053 #define CSEL1 14 // CS1 Bit // swap pin assignments with CSEL2 if left/right image is reversed 00054 #define CSEL2 15 // CS2 Bit 00055 #define R_W 16 // R/W Bit 00056 #define D_I 17 // D/I Bit 00057 #define EN 18 // EN Bit 00058 00059 /* Arduino pins used for LCD Data 00060 * un-comment ONE of the following pin options that corresponds to the wiring of data bits 0-3 00061 */ 00062 #define dataPins8to11 // bits 0-3 assigned to arduino pins 8-11, bits 4-7 assigned to arduino pins 4-7 00063 //#define dataPins14to17 //bits 0-3 assigned to arduino pins 14-17, bits 4-7 assigned to arduino pins 4-7. (note command pins must be changed) 00064 //#define dataPins0to3 // bits 0-3 assigned to arduino pins 0-3 , bits 4-7 assigned to arduino pins 4-7, this is marginally the fastest option but its only available on runtime board without hardware rs232. 00065 00066 /* NOTE: all above options assume LCD data bits 4-7 are connected to arduino pins 4-7 */ 00067 /*******************************************************/ 00068 /* end of Arduino pin configuration */ 00069 /*******************************************************/ 00070 00071 /* option: uncomment the next line if all command pins are on the same port for slight speed & code size improvement */ 00072 //#define LCD_CMD_PORT PORTC // Command Output Register 00073 00074 //#define HD44102 // uncomment this to build a 44102 version 00075 00076 #ifndef dataPins0to3 // this is the only option on standard arduino where all data bits are on same port 00077 #define LCD_DATA_NIBBLES // if this is defined then data i/o is split into two operations 00078 #endif 00079 00080 // these macros map pins to ports using the defines above 00081 // the following should not be changed unless you really know what your doing 00082 #ifdef dataPins0to3 00083 #define LCD_DATA_LOW_NBL D // port for low nibble: D=pins 0-3 00084 #endif 00085 #ifdef dataPins14to17 00086 #define LCD_DATA_LOW_NBL C // port for low nibble: C=pins 14-17 (using this requires reasignment of command pins) 00087 #endif 00088 #ifdef dataPins8to11 // the following is the defualt setting 00089 #define LCD_DATA_LOW_NBL B // port for low nibble, B=pins 8-11 00090 #endif 00091 00092 #define LCD_DATA_HIGH_NBL D // port for high nibble: D=pins 4-7, B & C not available on std arduino 00093 00094 // macros for pasting port defines 00095 #define GLUE(a, b) a##b 00096 #define PORT(x) GLUE(PORT, x) 00097 #define PIN(x) GLUE(PIN, x) 00098 #define DDR(x) GLUE(DDR, x) 00099 00100 // paste together the port definitions if using nibbles 00101 #define LCD_DATA_IN_LOW PIN(LCD_DATA_LOW_NBL) // Data I/O Register, low nibble 00102 #define LCD_DATA_OUT_LOW PORT(LCD_DATA_LOW_NBL) // Data Output Register - low nibble 00103 #define LCD_DATA_DIR_LOW DDR(LCD_DATA_LOW_NBL) // Data Direction Register for Data Port, low nibble 00104 00105 #define LCD_DATA_IN_HIGH PIN(LCD_DATA_HIGH_NBL) // Data Input Register high nibble 00106 #define LCD_DATA_OUT_HIGH PORT(LCD_DATA_HIGH_NBL) // Data Output Register - high nibble 00107 #define LCD_DATA_DIR_HIGH DDR(LCD_DATA_HIGH_NBL) // Data Direction Register for Data Port, high nibble 00108 00109 #define lcdDataOut(_val_) LCD_DATA_OUT(_val_) 00110 #define lcdDataDir(_val_) LCD_DATA_DIR(_val_) 00111 00112 // macros to handle data output 00113 #ifdef LCD_DATA_NIBBLES // data is split over two ports 00114 #define LCD_DATA_OUT(_val_) \ 00115 LCD_DATA_OUT_LOW = (LCD_DATA_OUT_LOW & 0xF0)| (_val_ & 0x0F); LCD_DATA_OUT_HIGH = (LCD_DATA_OUT_HIGH & 0x0F)| (_val_ & 0xF0); 00116 00117 #define LCD_DATA_DIR(_val_)\ 00118 LCD_DATA_DIR_LOW = (LCD_DATA_DIR_LOW & 0xF0)| (_val_ & 0x0F); LCD_DATA_DIR_HIGH = (LCD_DATA_DIR_HIGH & 0x0F)| (_val_ & 0xF0); 00119 #else // all data on same port (low equals high) 00120 #define LCD_DATA_OUT(_val_) LCD_DATA_OUT_LOW = (_val_); 00121 #define LCD_DATA_DIR(_val_) LCD_DATA_DIR_LOW = (_val_); 00122 #endif 00123 00124 00125 // macros to fast write data to pins known at compile time, this is over 30 times faster than digitalWrite 00126 #define fastWriteHigh(_pin_) ( _pin_ < 8 ? PORTD |= 1 << (_pin_ & 0x07) : ( _pin_ < 14 ? PORTB |= 1 << ((_pin_ -8) & 0x07) : PORTC |= 1 << ((_pin_ -14) & 0x07) ) ) 00127 #define fastWriteLow(_pin_) ( _pin_ < 8 ? PORTD &= ~(1 << (_pin_ & 0x07)) : ( _pin_ < 14 ? PORTB &= ~(1 << ((_pin_ -8) & 0x07) ) : PORTC &= ~(1 << ((_pin_ -14) & 0x07) ) ) ) 00128 00129 // Chips 00130 #define CHIP1 0x00 00131 #define CHIP2 0x01 00132 #ifdef HD44102 00133 #define CHIP_WIDTH 50 // pixels per chip 00134 #else 00135 #define CHIP_WIDTH 64 00136 #endif 00137 00138 // Commands 00139 #ifdef HD44102 00140 #define LCD_ON 0x39 00141 #define LCD_OFF 0x38 00142 #define LCD_DISP_START 0x3E // Display start page 0 00143 #else 00144 #define LCD_ON 0x3F 00145 #define LCD_OFF 0x3E 00146 #define LCD_DISP_START 0xC0 00147 #endif 00148 00149 #define LCD_SET_ADD 0x40 00150 #define LCD_SET_PAGE 0xB8 00151 00152 00153 // Colors 00154 #define BLACK 0xFF 00155 #define WHITE 0x00 00156 00157 // useful user contants 00158 #define NON_INVERTED false 00159 #define INVERTED true 00160 00161 // Font Indices 00162 #define FONT_LENGTH 0 00163 #define FONT_FIXED_WIDTH 2 00164 #define FONT_HEIGHT 3 00165 #define FONT_FIRST_CHAR 4 00166 #define FONT_CHAR_COUNT 5 00167 #define FONT_WIDTH_TABLE 6 00168 00169 #ifdef HD44102 00170 #define DISPLAY_WIDTH 100 00171 #define DISPLAY_HEIGHT 32 00172 #else 00173 #define DISPLAY_WIDTH 128 00174 #define DISPLAY_HEIGHT 64 00175 #endif 00176 00177 // Uncomment for slow drawing 00178 // #define DEBUG 00179 00180 typedef struct { 00181 uint8_t x; 00182 uint8_t y; 00183 uint8_t page; 00184 } lcdCoord; 00185 00186 typedef uint8_t (*FontCallback)(const uint8_t*); 00187 00188 uint8_t ReadFontData(const uint8_t* ptr); //Standard Read Callback 00189 00190 #define DrawVertLine(x, y, length, color) FillRect(x, y, 1, length, color) 00191 #define DrawHoriLine(x, y, length, color) FillRect(x, y, length, 1, color) 00192 #define DrawCircle(xCenter, yCenter, radius, color) DrawRoundRect(xCenter-radius, yCenter-radius, 2*radius, 2*radius, radius, color) 00193 #define ClearScreen() FillRect(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT, WHITE) 00194 00195 class ks0108iLab // shell class for ks0108iLab glcd code 00196 { 00197 public: 00198 ks0108iLab(); 00199 // Control functions 00200 void Init(boolean invert); 00201 void GotoXY(uint8_t x, uint8_t y); 00202 // Graphic Functions 00203 void DrawLine(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, uint8_t color); 00204 void DrawRect(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t color); 00205 void DrawRoundRect(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t radius, uint8_t color); 00206 void FillRect(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t color); 00207 void InvertRect(uint8_t x, uint8_t y, uint8_t width, uint8_t height); 00208 void SetInverted(boolean invert); 00209 void SetDot(uint8_t x, uint8_t y, uint8_t color); 00210 void DrawBarGraph(uint8_t y, int8_t val); 00211 00212 // Font Functions 00213 void SelectFont(const uint8_t* font, uint8_t color=BLACK, FontCallback callback=ReadFontData); // defualt arguments added, callback now last arg 00214 int PutChar(char c); 00215 void Puts(char* str); 00216 void PutsCentered(char* str, uint8_t x, uint8_t y, uint8_t width); 00217 void Puts_P(PGM_P str); 00218 void PrintNumber(long n); 00219 void PrintNumberCentered(long n, uint8_t x, uint8_t y, uint8_t width); 00220 00221 uint8_t CharWidth(char c); 00222 uint16_t StringWidth(char* str); 00223 uint16_t StringWidth_P(PGM_P str); 00224 00225 00226 private: 00227 lcdCoord Coord; 00228 boolean Inverted; // changed type to boolean 00229 FontCallback FontRead; 00230 uint8_t FontColor; 00231 const uint8_t* Font; 00232 uint8_t ReadData(void); // TODO this was inline !!! 00233 uint8_t DoReadData(uint8_t first); 00234 void WriteData(uint8_t data); 00235 void WriteCommand(uint8_t cmd, uint8_t chip); 00236 inline void Enable(void); 00237 }; 00238 00239 extern ks0108iLab GLCDiLab; 00240 #endif