for ST7567 LCD

Dependents:   BSM02

Fork of st7565LCD by Masato YAMANISHI

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers st7565LCD.cpp Source File

st7565LCD.cpp

00001 /*
00002 $Id:$
00003 
00004 ST7565 LCD library!
00005 
00006 Copyright (C) 2010 Limor Fried, Adafruit Industries
00007 
00008 This library is free software; you can redistribute it and/or
00009 modify it under the terms of the GNU Lesser General Public
00010 License as published by the Free Software Foundation; either
00011 version 2.1 of the License, or (at your option) any later version.
00012 
00013 This library is distributed in the hope that it will be useful,
00014 but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016 Lesser General Public License for more details.
00017 
00018 You should have received a copy of the GNU Lesser General Public
00019 License along with this library; if not, write to the Free Software
00020 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00021 
00022 // some of this code was written by <cstone@pobox.com> originally; it is in the public domain.
00023 
00024 
00025 ******the library is modified for mbed**********
00026     http://www.adafruit.com/products/250
00027     
00028     *!function drawbitmap(); is left undone!*
00029     
00030                     2014/03/18     by imachooon
00031                     mailto: imachooon@gmail.com
00032 ************************************************
00033 */
00034 
00035 #include "st7565LCD.h"
00036 #include "st7565LCDfont.h"
00037 
00038 #define ST7567 //
00039 
00040 #ifdef ST7567
00041 #define ST7565_STARTBYTES 0 
00042 const uint8_t pagemap[] = { 7, 6, 5, 4, 3, 2, 1, 0 };
00043 #else
00044 #define ST7565_STARTBYTES 1
00045 const uint8_t pagemap[] = { 3, 2, 1, 0, 7, 6, 5, 4 };
00046 #endif
00047 
00048 uint8_t is_reversed = 0;
00049 
00050 // a handy reference to where the pages are on the screen
00051 
00052 // a 5x7 font table
00053 extern const uint8_t font[];
00054 
00055 // the memory buffer for the LCD
00056 uint8_t st7565_buffer[1024] = {
00057     0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
00058     0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
00059     0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
00060     0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
00061     0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
00062     0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
00063     0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
00064     0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
00065 
00066     0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
00067     0x0, 0x0, 0x0, 0x3, 0x7, 0xF, 0x1F, 0x1F, 0x3F, 0x3F, 0x3F, 0x3F, 0x7, 0x0, 0x0, 0x0,
00068     0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
00069     0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
00070     0x0, 0x0, 0x7F, 0x3F, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
00071     0x0, 0x0, 0x1F, 0x3F, 0x70, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
00072     0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0x6, 0x0, 0x0, 0x0, 0x3, 0x3,
00073     0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
00074 
00075     0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0xF, 0x7, 0x7,
00076     0x7, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3E, 0x0, 0x0,
00077     0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xF, 0x3F,
00078     0x70, 0x60, 0x60, 0x60, 0x60, 0x30, 0x7F, 0x3F, 0x0, 0x0, 0x1F, 0x3F, 0x70, 0x60, 0x60, 0x60,
00079     0x60, 0x39, 0xFF, 0xFF, 0x0, 0x6, 0x1F, 0x39, 0x60, 0x60, 0x60, 0x60, 0x30, 0x3F, 0x7F, 0x0,
00080     0x0, 0x60, 0xFF, 0xFF, 0x60, 0x60, 0x0, 0x7F, 0x7F, 0x70, 0x60, 0x60, 0x40, 0x0, 0x7F, 0x7F,
00081     0x0, 0x0, 0x0, 0x0, 0x7F, 0x7F, 0x0, 0x0, 0x0, 0x7F, 0x7F, 0x0, 0x0, 0x60, 0xFF, 0xFF,
00082     0x60, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
00083 
00084     0x80, 0xF8, 0xFC, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0xE7, 0xE7, 0xE3,
00085     0xF3, 0xF9, 0xFF, 0xFF, 0xFF, 0xF7, 0x7, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF,
00086     0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x3F, 0x3F, 0x1F, 0xF, 0x7, 0x3, 0x0, 0x0, 0x0, 0xC0,
00087     0xE0, 0x60, 0x20, 0x20, 0x60, 0xE0, 0xE0, 0xE0, 0x0, 0x0, 0x80, 0xC0, 0xE0, 0x60, 0x20, 0x60,
00088     0x60, 0xE0, 0xE0, 0xE0, 0x0, 0x0, 0x80, 0xC0, 0x60, 0x60, 0x20, 0x60, 0x60, 0xE0, 0xE0, 0x0,
00089     0x0, 0x0, 0xE0, 0xE0, 0x0, 0x0, 0x0, 0xE0, 0xE0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, 0xE0,
00090     0x60, 0x60, 0x60, 0x60, 0xE0, 0x80, 0x0, 0x0, 0x0, 0xE0, 0xE0, 0x0, 0x0, 0x0, 0xE0, 0xE0,
00091     0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
00092 
00093     0x0, 0x0, 0x0, 0x3, 0x7, 0x1F, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xF1, 0xE3,
00094     0xE3, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xFC, 0x7F, 0x3F, 0x3F, 0x3F, 0x3F, 0x7F, 0xFF, 0xFF,
00095     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFC, 0xF0, 0xE0, 0x80, 0x0, 0x0, 0x0, 0xC,
00096     0x1C, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
00097     0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7F, 0x7F, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
00098     0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0x7, 0x0,
00099     0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1C, 0xC, 0x0, 0x0, 0x0, 0x0, 0x0,
00100     0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
00101 
00102     0x0, 0x7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFE, 0xFC, 0xF8,
00103     0xF8, 0xF0, 0xFE, 0xFF, 0xFF, 0xFF, 0x7F, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F,
00104     0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xFF,
00105     0xFF, 0x0, 0x0, 0x0, 0xFF, 0xFF, 0xE0, 0xC0, 0xC0, 0xC0, 0xFF, 0x7F, 0x0, 0x0, 0x1E, 0x7F,
00106     0xE1, 0xC0, 0xC0, 0xC0, 0xC0, 0x61, 0xFF, 0xFF, 0x0, 0x0, 0xFE, 0xFF, 0x1, 0x0, 0x0, 0x0,
00107     0xFF, 0xFF, 0x0, 0x0, 0x21, 0xF9, 0xF8, 0xDC, 0xCC, 0xCF, 0x7, 0x0, 0xC0, 0xFF, 0xFF, 0xC0,
00108     0x80, 0x0, 0xFF, 0xFF, 0xC0, 0xC0, 0x80, 0x0, 0x0, 0xFF, 0xFF, 0x0, 0x0, 0x1F, 0x7F, 0xF9,
00109     0xC8, 0xC8, 0xC8, 0xC8, 0x79, 0x39, 0x0, 0x0, 0x71, 0xF9, 0xD8, 0xCC, 0xCE, 0x47, 0x3, 0x0,
00110 
00111     0x0, 0x0, 0x0, 0x0, 0x80, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
00112     0x0, 0x0, 0x0, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xF8, 0xFC, 0xFC, 0xFC, 0xFC, 0xF8, 0xF0, 0xC0,
00113     0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xC0,
00114     0xC0, 0x0, 0x0, 0x0, 0xC0, 0xC0, 0x0, 0x0, 0x0, 0x0, 0xC0, 0xC0, 0x0, 0x0, 0x0, 0x80,
00115     0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x80, 0xC0, 0xC0, 0x0, 0x0, 0x0, 0x80, 0xC0, 0xC0, 0xC0, 0xC0,
00116     0xC0, 0x80, 0x0, 0x0, 0x80, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x0, 0x0, 0x0, 0xC0, 0xC0, 0x0,
00117     0x0, 0x0, 0xC0, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0xC0, 0xC0, 0x0, 0x0, 0x0, 0x80, 0xC0,
00118     0xC0, 0xC0, 0xC0, 0xC0, 0x80, 0x80, 0x0, 0x0, 0x80, 0xC0, 0xC0, 0xC0, 0xC0, 0x80, 0x0, 0x0,
00119 
00120     0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
00121     0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
00122     0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
00123     0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
00124     0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
00125     0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
00126     0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
00127     0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
00128 };
00129 
00130 
00131 
00132 
00133 // reduces how much is refreshed, which speeds it up!
00134 // originally derived from Steve Evans/JCW's mod but cleaned up and
00135 // optimized
00136 #define enablePartialUpdate
00137 
00138 #ifdef enablePartialUpdate
00139 static uint8_t xUpdateMin, xUpdateMax, yUpdateMin, yUpdateMax;
00140 #endif
00141 
00142 
00143 
00144 static void updateBoundingBox(uint8_t xmin, uint8_t ymin, uint8_t xmax, uint8_t ymax)
00145 {
00146 #ifdef enablePartialUpdate
00147     if (xmin < xUpdateMin) xUpdateMin = xmin;
00148     if (xmax > xUpdateMax) xUpdateMax = xmax;
00149     if (ymin < yUpdateMin) yUpdateMin = ymin;
00150     if (ymax > yUpdateMax) yUpdateMax = ymax;
00151 #endif
00152 }
00153 
00154 /*
00155 void ST7565::drawbitmap(uint8_t x, uint8_t y,
00156             const uint8_t *bitmap, uint8_t w, uint8_t h,
00157             uint8_t color) {
00158   for (uint8_t i=0; i<h; i++) {
00159     for (uint8_t j=0; j<w; j++ ) {
00160       if (pgm_read_byte(bitmap + j + (j/8)*w) & _BV(j%8)) {
00161     my_setpixel(x+j, y+i, color);
00162       }
00163     }
00164   }
00165 
00166   updateBoundingBox(x, y, x+w, y+h);
00167 }
00168 */
00169 
00170 void ST7565::drawstring(uint8_t x, uint8_t line, char *c)
00171 {
00172     while (*c != '\0') {
00173         drawchar(x, line, *c);
00174         *c++;
00175         x += 6; // 6 pixels wide
00176         if (x + 6 >= LCDWIDTH) {
00177             x = 0;    // ran out of this line
00178             line++;
00179         }
00180         if (line >= (LCDHEIGHT/8))
00181             return;        // ran out of space :(
00182     }
00183 }
00184 
00185 
00186 void  ST7565::drawchar(uint8_t x, uint8_t line, char c)
00187 {
00188     for (uint8_t i =0; i<5; i++ ) {
00189         *(st7565_buffer + x + line*128) = *(font + (c*5) + i);
00190         x++;
00191     }
00192     updateBoundingBox(x, line*8, x+5, line*8+8);    //only updates relevant area of LCD
00193 }
00194 
00195 
00196 // bresenham's algorithm - thx wikpedia
00197 void ST7565::drawline(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1,
00198                       uint8_t color)
00199 {
00200     uint8_t steep = abs(y1 - y0) > abs(x1 - x0);
00201     if (steep) {
00202         swap(x0, y0);
00203         swap(x1, y1);
00204     }
00205 
00206     if (x0 > x1) {
00207         swap(x0, x1);
00208         swap(y0, y1);
00209     }
00210 
00211     // much faster to put the test here, since we've already sorted the points
00212     updateBoundingBox(x0, y0, x1, y1);
00213 
00214     uint8_t dx, dy;
00215     dx = x1 - x0;
00216     dy = abs(y1 - y0);
00217 
00218     int8_t err = dx / 2;
00219     int8_t ystep;
00220 
00221     if (y0 < y1) {
00222         ystep = 1;
00223     } else {
00224         ystep = -1;
00225     }
00226 
00227     for (; x0<=x1; x0++) {
00228         if (steep) {
00229             my_setpixel(y0, x0, color);
00230         } else {
00231             my_setpixel(x0, y0, color);
00232         }
00233         err -= dy;
00234         if (err < 0) {
00235             y0 += ystep;
00236             err += dx;
00237         }
00238     }
00239 }
00240 
00241 // filled rectangle
00242 void ST7565::fillrect(uint8_t x, uint8_t y, uint8_t w, uint8_t h,
00243                       uint8_t color)
00244 {
00245 
00246     // stupidest version - just pixels - but fast with internal buffer!
00247     for (uint8_t i=x; i<x+w; i++) {
00248         for (uint8_t j=y; j<y+h; j++) {
00249             my_setpixel(i, j, color);
00250         }
00251     }
00252 
00253     updateBoundingBox(x, y, x+w, y+h);
00254 }
00255 
00256 // draw a rectangle
00257 void ST7565::drawrect(uint8_t x, uint8_t y, uint8_t w, uint8_t h,
00258                       uint8_t color)
00259 {
00260     // stupidest version - just pixels - but fast with internal buffer!
00261     for (uint8_t i=x; i<x+w; i++) {
00262         my_setpixel(i, y, color);
00263         my_setpixel(i, y+h-1, color);
00264     }
00265     for (uint8_t i=y; i<y+h; i++) {
00266         my_setpixel(x, i, color);
00267         my_setpixel(x+w-1, i, color);
00268     }
00269 
00270     updateBoundingBox(x, y, x+w, y+h);
00271 }
00272 
00273 // draw a circle outline
00274 void ST7565::drawcircle(uint8_t x0, uint8_t y0, uint8_t r,
00275                         uint8_t color)
00276 {
00277     updateBoundingBox(x0-r, y0-r, x0+r, y0+r);
00278 
00279     int8_t f = 1 - r;
00280     int8_t ddF_x = 1;
00281     int8_t ddF_y = -2 * r;
00282     int8_t x = 0;
00283     int8_t y = r;
00284 
00285     my_setpixel(x0, y0+r, color);
00286     my_setpixel(x0, y0-r, color);
00287     my_setpixel(x0+r, y0, color);
00288     my_setpixel(x0-r, y0, color);
00289 
00290     while (x<y) {
00291         if (f >= 0) {
00292             y--;
00293             ddF_y += 2;
00294             f += ddF_y;
00295         }
00296         x++;
00297         ddF_x += 2;
00298         f += ddF_x;
00299 
00300         my_setpixel(x0 + x, y0 + y, color);
00301         my_setpixel(x0 - x, y0 + y, color);
00302         my_setpixel(x0 + x, y0 - y, color);
00303         my_setpixel(x0 - x, y0 - y, color);
00304 
00305         my_setpixel(x0 + y, y0 + x, color);
00306         my_setpixel(x0 - y, y0 + x, color);
00307         my_setpixel(x0 + y, y0 - x, color);
00308         my_setpixel(x0 - y, y0 - x, color);
00309 
00310     }
00311 }
00312 
00313 void ST7565::fillcircle(uint8_t x0, uint8_t y0, uint8_t r,
00314                         uint8_t color)
00315 {
00316     updateBoundingBox(x0-r, y0-r, x0+r, y0+r);
00317 
00318     int8_t f = 1 - r;
00319     int8_t ddF_x = 1;
00320     int8_t ddF_y = -2 * r;
00321     int8_t x = 0;
00322     int8_t y = r;
00323 
00324     for (uint8_t i=y0-r; i<=y0+r; i++) {
00325         my_setpixel(x0, i, color);
00326     }
00327 
00328     while (x<y) {
00329         if (f >= 0) {
00330             y--;
00331             ddF_y += 2;
00332             f += ddF_y;
00333         }
00334         x++;
00335         ddF_x += 2;
00336         f += ddF_x;
00337 
00338         for (uint8_t i=y0-y; i<=y0+y; i++) {
00339             my_setpixel(x0+x, i, color);
00340             my_setpixel(x0-x, i, color);
00341         }
00342         for (uint8_t i=y0-x; i<=y0+x; i++) {
00343             my_setpixel(x0+y, i, color);
00344             my_setpixel(x0-y, i, color);
00345         }
00346     }
00347 }
00348 
00349 void ST7565::my_setpixel(uint8_t x, uint8_t y, uint8_t color)
00350 {
00351     if ((x >= LCDWIDTH) || (y >= LCDHEIGHT))
00352         return;
00353 
00354     // x is which column
00355     if (color)
00356         st7565_buffer[x+ (y/8)*128] |= _BV(7-(y%8));
00357     else
00358         st7565_buffer[x+ (y/8)*128] &= _nBV(7-(y%8));
00359 }
00360 
00361 // the most basic function, set a single pixel
00362 void ST7565::setpixel(uint8_t x, uint8_t y, uint8_t color)
00363 {
00364     if ((x >= LCDWIDTH) || (y >= LCDHEIGHT))
00365         return;
00366     // x is which column
00367     if (color)
00368         st7565_buffer[x+ (y/8)*128] |= _BV(7-(y%8));
00369     else
00370         st7565_buffer[x+ (y/8)*128] &= _nBV(7-(y%8));
00371 
00372     updateBoundingBox(x,y,x,y);
00373 }
00374 
00375 
00376 // the most basic function, get a single pixel
00377 uint8_t ST7565::getpixel(uint8_t x, uint8_t y)
00378 {
00379     if ((x >= LCDWIDTH) || (y >= LCDHEIGHT))
00380         return 0;
00381 
00382     return (st7565_buffer[x+ (y/8)*128] >> (7-(y%8))) & 0x1;
00383 }
00384 
00385 
00386 ST7565::ST7565(PinName mosi, PinName sclk, PinName cs, PinName rst, PinName a0)
00387 // set pin directions
00388     : _spi(mosi, NC, sclk), _cs(cs), _rst(rst), _a0(a0)
00389 
00390 {
00391     _spi.format(8, 0);
00392     _spi.frequency(1000000);
00393 }
00394 
00395 void ST7565::set_spi_frequency(int frequency)
00396 {
00397     _spi.frequency(frequency);
00398 }
00399 
00400 void ST7565::st7565_init(void)
00401 {
00402     wait_ms(100); 
00403     _rst = 0;
00404     wait_ms(100);
00405     _rst = 1;
00406     
00407 
00408     // LCD bias select
00409     st7565_command(CMD_SET_BIAS_7);
00410     // ADC select
00411     st7565_command(CMD_SET_ADC_NORMAL);
00412     // SHL select
00413     st7565_command(CMD_SET_COM_NORMAL);
00414 
00415     // turn on voltage converter (VC=1, VR=0, VF=0)
00416     st7565_command(CMD_SET_POWER_CONTROL | 0x4);
00417     // wait for 50% rising
00418     wait_ms(50);
00419 
00420     // turn on voltage regulator (VC=1, VR=1, VF=0)
00421     st7565_command(CMD_SET_POWER_CONTROL | 0x6);
00422     // wait >=50ms
00423     wait_ms(20);
00424 
00425     // turn on voltage follower (VC=1, VR=1, VF=1)
00426     st7565_command(CMD_SET_POWER_CONTROL | 0x7);
00427     // wait
00428     wait_ms(10);
00429     
00430     // set lcd operating voltage (regulator resistor, ref voltage resistor)
00431     st7565_command(CMD_SET_RESISTOR_RATIO | 0x4);
00432     wait_ms(10);
00433 
00434 
00435 //    st7565_set_brightness(INITIAL_CONTRAST);
00436     // set up a bounding box for screen updates
00437     updateBoundingBox(0, 0, LCDWIDTH-1, LCDHEIGHT-1);
00438 
00439 
00440     st7565_command(CMD_DISPLAY_ON);
00441     st7565_command(CMD_SET_ALLPTS_NORMAL);
00442     
00443     
00444     // reference voltage resistor    
00445     st7565_command(CMD_SET_VOLUME_FIRST);
00446     wait_ms(10);
00447     st7565_command(CMD_SET_VOLUME_SECOND);
00448     wait_ms(10);
00449 
00450 
00451 
00452     // Initial display line ( = 0)
00453     st7565_command(CMD_SET_DISP_START_LINE);
00454     // Initial page address ( = 0)
00455     st7565_command(CMD_SET_PAGE);    
00456     st7565_command(CMD_SET_COLUMN_UPPER);
00457     st7565_command(CMD_SET_COLUMN_LOWER);
00458     
00459 }
00460 
00461 inline void ST7565::spiwrite(uint8_t c)
00462 {
00463     _spi.write(c);
00464 }
00465 
00466 void ST7565::st7565_command(uint8_t c)
00467 {
00468     _cs = 0;
00469     _a0 = 0;
00470     _spi.write(c);
00471     _cs = 1;
00472 }
00473 
00474 void ST7565::st7565_data(uint8_t c)
00475 {
00476     _cs = 0;
00477     _a0 = 1;
00478     _spi.write(c);
00479     _cs = 1;
00480 }
00481 
00482 void ST7565::st7565_set_brightness(uint8_t val)
00483 {
00484     st7565_command(CMD_SET_VOLUME_FIRST);
00485     st7565_command(CMD_SET_VOLUME_SECOND | (val & 0x3f));
00486 }
00487 
00488 void ST7565::begin(uint8_t contrast){
00489     st7565_init();
00490   st7565_command(CMD_DISPLAY_ON);
00491   st7565_command(CMD_SET_ALLPTS_NORMAL);
00492   st7565_set_brightness(contrast);
00493 }
00494     
00495 
00496 void ST7565::display(void)
00497 {
00498     uint8_t col, maxcol, p;
00499 
00500     for(p = 0; p < 8; p++) {
00501 #ifdef enablePartialUpdate
00502         // check if this page is part of update
00503         if ( yUpdateMin >= ((p+1)*8) ) {
00504             continue;   // nope, skip it!
00505         }
00506         if (yUpdateMax < p*8) {
00507             break;
00508         }
00509 #endif
00510         st7565_command(CMD_SET_PAGE | pagemap[p]);
00511 
00512 #ifdef enablePartialUpdate
00513         col = xUpdateMin;
00514         maxcol = xUpdateMax;
00515 #else
00516         // start at the beginning of the row
00517         col = 0;
00518         maxcol = LCDWIDTH-1;
00519 #endif
00520 
00521         st7565_command(CMD_SET_COLUMN_LOWER | ((col+ST7565_STARTBYTES) & 0xf));
00522         st7565_command(CMD_SET_COLUMN_UPPER | (((col+ST7565_STARTBYTES) >> 4) & 0x0F));
00523         st7565_command(CMD_RMW);
00524 
00525         for(; col <= maxcol; col++) {
00526             st7565_data(st7565_buffer[(128*p)+col]);
00527         }
00528     }
00529 
00530 #ifdef enablePartialUpdate
00531     xUpdateMin = LCDWIDTH - 1;
00532     xUpdateMax = 0;
00533     yUpdateMin = LCDHEIGHT-1;
00534     yUpdateMax = 0;
00535 #endif
00536 }
00537 
00538 // clear everything
00539 void ST7565::clear(void)
00540 {
00541     memset(st7565_buffer, 0, 1024);
00542     updateBoundingBox(0, 0, LCDWIDTH-1, LCDHEIGHT-1);
00543 }
00544 
00545 
00546 // this doesnt touch the buffer, just clears the display RAM - might be handy
00547 void ST7565::clear_display(void)
00548 {
00549     uint8_t p, c;
00550 
00551     for(p = 0; p < 8; p++) {
00552 
00553         st7565_command(CMD_SET_PAGE | p);
00554         for(c = 0; c < 129; c++) {
00555             st7565_command(CMD_SET_COLUMN_LOWER | (c & 0xf));
00556             st7565_command(CMD_SET_COLUMN_UPPER | ((c >> 4) & 0xf));
00557             st7565_data(0x0);
00558         }
00559     }
00560 }
00561 
00562 //additional function to set a bit
00563 uint8_t ST7565::_BV(uint8_t bit)
00564 {
00565     return 1 << bit;
00566 }
00567 
00568 uint8_t ST7565::_nBV(uint8_t bit)
00569 {
00570     return 0 << bit;
00571 }