adapted for ST7567 (aitendo CH12864F-SPI)

Fork of st7565LCD by jun imamura

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 
00396 
00397 void ST7565::st7565_init(void)
00398 {
00399     wait_ms(100); 
00400     _rst = 0;
00401     wait_ms(100);
00402     _rst = 1;
00403     
00404 
00405     // LCD bias select
00406     st7565_command(CMD_SET_BIAS_7);
00407     // ADC select
00408     st7565_command(CMD_SET_ADC_NORMAL);
00409     // SHL select
00410     st7565_command(CMD_SET_COM_NORMAL);
00411 
00412     // turn on voltage converter (VC=1, VR=0, VF=0)
00413     st7565_command(CMD_SET_POWER_CONTROL | 0x4);
00414     // wait for 50% rising
00415     wait_ms(50);
00416 
00417     // turn on voltage regulator (VC=1, VR=1, VF=0)
00418     st7565_command(CMD_SET_POWER_CONTROL | 0x6);
00419     // wait >=50ms
00420     wait_ms(20);
00421 
00422     // turn on voltage follower (VC=1, VR=1, VF=1)
00423     st7565_command(CMD_SET_POWER_CONTROL | 0x7);
00424     // wait
00425     wait_ms(10);
00426     
00427     // set lcd operating voltage (regulator resistor, ref voltage resistor)
00428     st7565_command(CMD_SET_RESISTOR_RATIO | 0x4);
00429     wait_ms(10);
00430 
00431 
00432 //    st7565_set_brightness(INITIAL_CONTRAST);
00433     // set up a bounding box for screen updates
00434     updateBoundingBox(0, 0, LCDWIDTH-1, LCDHEIGHT-1);
00435 
00436 
00437     st7565_command(CMD_DISPLAY_ON);
00438     st7565_command(CMD_SET_ALLPTS_NORMAL);
00439     
00440     
00441     // reference voltage resistor    
00442     st7565_command(CMD_SET_VOLUME_FIRST);
00443     wait_ms(10);
00444     st7565_command(CMD_SET_VOLUME_SECOND);
00445     wait_ms(10);
00446 
00447 
00448 
00449     // Initial display line ( = 0)
00450     st7565_command(CMD_SET_DISP_START_LINE);
00451     // Initial page address ( = 0)
00452     st7565_command(CMD_SET_PAGE);    
00453     st7565_command(CMD_SET_COLUMN_UPPER);
00454     st7565_command(CMD_SET_COLUMN_LOWER);
00455     
00456 }
00457 
00458 inline void ST7565::spiwrite(uint8_t c)
00459 {
00460     _spi.write(c);
00461 }
00462 
00463 void ST7565::st7565_command(uint8_t c)
00464 {
00465     _cs = 0;
00466     _a0 = 0;
00467     _spi.write(c);
00468     _cs = 1;
00469 }
00470 
00471 void ST7565::st7565_data(uint8_t c)
00472 {
00473     _cs = 0;
00474     _a0 = 1;
00475     _spi.write(c);
00476     _cs = 1;
00477 }
00478 
00479 void ST7565::st7565_set_brightness(uint8_t val)
00480 {
00481     st7565_command(CMD_SET_VOLUME_FIRST);
00482     st7565_command(CMD_SET_VOLUME_SECOND | (val & 0x3f));
00483 }
00484 
00485 void ST7565::begin(uint8_t contrast){
00486     st7565_init();
00487   st7565_command(CMD_DISPLAY_ON);
00488   st7565_command(CMD_SET_ALLPTS_NORMAL);
00489   st7565_set_brightness(contrast);
00490 }
00491     
00492 
00493 void ST7565::display(void)
00494 {
00495     uint8_t col, maxcol, p;
00496 
00497     for(p = 0; p < 8; p++) {
00498 #ifdef enablePartialUpdate
00499         // check if this page is part of update
00500         if ( yUpdateMin >= ((p+1)*8) ) {
00501             continue;   // nope, skip it!
00502         }
00503         if (yUpdateMax < p*8) {
00504             break;
00505         }
00506 #endif
00507         st7565_command(CMD_SET_PAGE | pagemap[p]);
00508 
00509 #ifdef enablePartialUpdate
00510         col = xUpdateMin;
00511         maxcol = xUpdateMax;
00512 #else
00513         // start at the beginning of the row
00514         col = 0;
00515         maxcol = LCDWIDTH-1;
00516 #endif
00517 
00518         st7565_command(CMD_SET_COLUMN_LOWER | ((col+ST7565_STARTBYTES) & 0xf));
00519         st7565_command(CMD_SET_COLUMN_UPPER | (((col+ST7565_STARTBYTES) >> 4) & 0x0F));
00520         st7565_command(CMD_RMW);
00521 
00522         for(; col <= maxcol; col++) {
00523             st7565_data(st7565_buffer[(128*p)+col]);
00524         }
00525     }
00526 
00527 #ifdef enablePartialUpdate
00528     xUpdateMin = LCDWIDTH - 1;
00529     xUpdateMax = 0;
00530     yUpdateMin = LCDHEIGHT-1;
00531     yUpdateMax = 0;
00532 #endif
00533 }
00534 
00535 // clear everything
00536 void ST7565::clear(void)
00537 {
00538     memset(st7565_buffer, 0, 1024);
00539     updateBoundingBox(0, 0, LCDWIDTH-1, LCDHEIGHT-1);
00540 }
00541 
00542 
00543 // this doesnt touch the buffer, just clears the display RAM - might be handy
00544 void ST7565::clear_display(void)
00545 {
00546     uint8_t p, c;
00547 
00548     for(p = 0; p < 8; p++) {
00549 
00550         st7565_command(CMD_SET_PAGE | p);
00551         for(c = 0; c < 129; c++) {
00552             st7565_command(CMD_SET_COLUMN_LOWER | (c & 0xf));
00553             st7565_command(CMD_SET_COLUMN_UPPER | ((c >> 4) & 0xf));
00554             st7565_data(0x0);
00555         }
00556     }
00557 }
00558 
00559 //additional function to set a bit
00560 uint8_t ST7565::_BV(uint8_t bit)
00561 {
00562     return 1 << bit;
00563 }
00564 
00565 uint8_t ST7565::_nBV(uint8_t bit)
00566 {
00567     return 0 << bit;
00568 }