Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of st7565LCD by
Diff: st7565LCD.cpp
- Revision:
- 0:f2eba6cbd093
- Child:
- 1:29ff79184a05
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/st7565LCD.cpp Tue Mar 18 09:26:16 2014 +0000
@@ -0,0 +1,561 @@
+/*
+$Id:$
+
+ST7565 LCD library!
+
+Copyright (C) 2010 Limor Fried, Adafruit Industries
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+// some of this code was written by <cstone@pobox.com> originally; it is in the public domain.
+
+
+******the library is modified for mbed**********
+ http://www.adafruit.com/products/250
+
+ *!function drawbitmap(); is left undone!*
+
+ 2014/03/18 by imachooon
+ mailto: imachooon@gmail.com
+************************************************
+*/
+
+#include "st7565LCD.h"
+#include "st7565LCDfont.h"
+
+#define ST7565_STARTBYTES 1
+
+uint8_t is_reversed = 0;
+
+// a handy reference to where the pages are on the screen
+const uint8_t pagemap[] = { 3, 2, 1, 0, 7, 6, 5, 4 };
+
+// a 5x7 font table
+extern const uint8_t font[];
+
+// the memory buffer for the LCD
+uint8_t st7565_buffer[1024] = {
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x3, 0x7, 0xF, 0x1F, 0x1F, 0x3F, 0x3F, 0x3F, 0x3F, 0x7, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x7F, 0x3F, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x1F, 0x3F, 0x70, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0x6, 0x0, 0x0, 0x0, 0x3, 0x3,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+
+ 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0xF, 0x7, 0x7,
+ 0x7, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3E, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xF, 0x3F,
+ 0x70, 0x60, 0x60, 0x60, 0x60, 0x30, 0x7F, 0x3F, 0x0, 0x0, 0x1F, 0x3F, 0x70, 0x60, 0x60, 0x60,
+ 0x60, 0x39, 0xFF, 0xFF, 0x0, 0x6, 0x1F, 0x39, 0x60, 0x60, 0x60, 0x60, 0x30, 0x3F, 0x7F, 0x0,
+ 0x0, 0x60, 0xFF, 0xFF, 0x60, 0x60, 0x0, 0x7F, 0x7F, 0x70, 0x60, 0x60, 0x40, 0x0, 0x7F, 0x7F,
+ 0x0, 0x0, 0x0, 0x0, 0x7F, 0x7F, 0x0, 0x0, 0x0, 0x7F, 0x7F, 0x0, 0x0, 0x60, 0xFF, 0xFF,
+ 0x60, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+
+ 0x80, 0xF8, 0xFC, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0xE7, 0xE7, 0xE3,
+ 0xF3, 0xF9, 0xFF, 0xFF, 0xFF, 0xF7, 0x7, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF,
+ 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x3F, 0x3F, 0x1F, 0xF, 0x7, 0x3, 0x0, 0x0, 0x0, 0xC0,
+ 0xE0, 0x60, 0x20, 0x20, 0x60, 0xE0, 0xE0, 0xE0, 0x0, 0x0, 0x80, 0xC0, 0xE0, 0x60, 0x20, 0x60,
+ 0x60, 0xE0, 0xE0, 0xE0, 0x0, 0x0, 0x80, 0xC0, 0x60, 0x60, 0x20, 0x60, 0x60, 0xE0, 0xE0, 0x0,
+ 0x0, 0x0, 0xE0, 0xE0, 0x0, 0x0, 0x0, 0xE0, 0xE0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, 0xE0,
+ 0x60, 0x60, 0x60, 0x60, 0xE0, 0x80, 0x0, 0x0, 0x0, 0xE0, 0xE0, 0x0, 0x0, 0x0, 0xE0, 0xE0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+
+ 0x0, 0x0, 0x0, 0x3, 0x7, 0x1F, 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xF1, 0xE3,
+ 0xE3, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xFC, 0x7F, 0x3F, 0x3F, 0x3F, 0x3F, 0x7F, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFC, 0xF0, 0xE0, 0x80, 0x0, 0x0, 0x0, 0xC,
+ 0x1C, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7F, 0x7F, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0x7, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1C, 0xC, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+
+ 0x0, 0x7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFE, 0xFC, 0xF8,
+ 0xF8, 0xF0, 0xFE, 0xFF, 0xFF, 0xFF, 0x7F, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xFF,
+ 0xFF, 0x0, 0x0, 0x0, 0xFF, 0xFF, 0xE0, 0xC0, 0xC0, 0xC0, 0xFF, 0x7F, 0x0, 0x0, 0x1E, 0x7F,
+ 0xE1, 0xC0, 0xC0, 0xC0, 0xC0, 0x61, 0xFF, 0xFF, 0x0, 0x0, 0xFE, 0xFF, 0x1, 0x0, 0x0, 0x0,
+ 0xFF, 0xFF, 0x0, 0x0, 0x21, 0xF9, 0xF8, 0xDC, 0xCC, 0xCF, 0x7, 0x0, 0xC0, 0xFF, 0xFF, 0xC0,
+ 0x80, 0x0, 0xFF, 0xFF, 0xC0, 0xC0, 0x80, 0x0, 0x0, 0xFF, 0xFF, 0x0, 0x0, 0x1F, 0x7F, 0xF9,
+ 0xC8, 0xC8, 0xC8, 0xC8, 0x79, 0x39, 0x0, 0x0, 0x71, 0xF9, 0xD8, 0xCC, 0xCE, 0x47, 0x3, 0x0,
+
+ 0x0, 0x0, 0x0, 0x0, 0x80, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xF8, 0xFC, 0xFC, 0xFC, 0xFC, 0xF8, 0xF0, 0xC0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xC0,
+ 0xC0, 0x0, 0x0, 0x0, 0xC0, 0xC0, 0x0, 0x0, 0x0, 0x0, 0xC0, 0xC0, 0x0, 0x0, 0x0, 0x80,
+ 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x80, 0xC0, 0xC0, 0x0, 0x0, 0x0, 0x80, 0xC0, 0xC0, 0xC0, 0xC0,
+ 0xC0, 0x80, 0x0, 0x0, 0x80, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x0, 0x0, 0x0, 0xC0, 0xC0, 0x0,
+ 0x0, 0x0, 0xC0, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0xC0, 0xC0, 0x0, 0x0, 0x0, 0x80, 0xC0,
+ 0xC0, 0xC0, 0xC0, 0xC0, 0x80, 0x80, 0x0, 0x0, 0x80, 0xC0, 0xC0, 0xC0, 0xC0, 0x80, 0x0, 0x0,
+
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+};
+
+
+
+
+// reduces how much is refreshed, which speeds it up!
+// originally derived from Steve Evans/JCW's mod but cleaned up and
+// optimized
+#define enablePartialUpdate
+
+#ifdef enablePartialUpdate
+static uint8_t xUpdateMin, xUpdateMax, yUpdateMin, yUpdateMax;
+#endif
+
+
+
+static void updateBoundingBox(uint8_t xmin, uint8_t ymin, uint8_t xmax, uint8_t ymax)
+{
+#ifdef enablePartialUpdate
+ if (xmin < xUpdateMin) xUpdateMin = xmin;
+ if (xmax > xUpdateMax) xUpdateMax = xmax;
+ if (ymin < yUpdateMin) yUpdateMin = ymin;
+ if (ymax > yUpdateMax) yUpdateMax = ymax;
+#endif
+}
+
+/*
+void ST7565::drawbitmap(uint8_t x, uint8_t y,
+ const uint8_t *bitmap, uint8_t w, uint8_t h,
+ uint8_t color) {
+ for (uint8_t i=0; i<h; i++) {
+ for (uint8_t j=0; j<w; j++ ) {
+ if (pgm_read_byte(bitmap + j + (j/8)*w) & _BV(j%8)) {
+ my_setpixel(x+j, y+i, color);
+ }
+ }
+ }
+
+ updateBoundingBox(x, y, x+w, y+h);
+}
+*/
+
+void ST7565::drawstring(uint8_t x, uint8_t line, char *c)
+{
+ while (*c != '\0') {
+ drawchar(x, line, *c);
+ *c++;
+ x += 6; // 6 pixels wide
+ if (x + 6 >= LCDWIDTH) {
+ x = 0; // ran out of this line
+ line++;
+ }
+ if (line >= (LCDHEIGHT/8))
+ return; // ran out of space :(
+ }
+}
+
+
+void ST7565::drawchar(uint8_t x, uint8_t line, char c)
+{
+ for (uint8_t i =0; i<5; i++ ) {
+ *(st7565_buffer + x + line*128) = *(font + (c*5) + i);
+ x++;
+ }
+ updateBoundingBox(x, line*8, x+5, line*8+8); //only updates relevant area of LCD
+}
+
+
+// bresenham's algorithm - thx wikpedia
+void ST7565::drawline(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1,
+ uint8_t color)
+{
+ uint8_t steep = abs(y1 - y0) > abs(x1 - x0);
+ if (steep) {
+ swap(x0, y0);
+ swap(x1, y1);
+ }
+
+ if (x0 > x1) {
+ swap(x0, x1);
+ swap(y0, y1);
+ }
+
+ // much faster to put the test here, since we've already sorted the points
+ updateBoundingBox(x0, y0, x1, y1);
+
+ uint8_t dx, dy;
+ dx = x1 - x0;
+ dy = abs(y1 - y0);
+
+ int8_t err = dx / 2;
+ int8_t ystep;
+
+ if (y0 < y1) {
+ ystep = 1;
+ } else {
+ ystep = -1;
+ }
+
+ for (; x0<=x1; x0++) {
+ if (steep) {
+ my_setpixel(y0, x0, color);
+ } else {
+ my_setpixel(x0, y0, color);
+ }
+ err -= dy;
+ if (err < 0) {
+ y0 += ystep;
+ err += dx;
+ }
+ }
+}
+
+// filled rectangle
+void ST7565::fillrect(uint8_t x, uint8_t y, uint8_t w, uint8_t h,
+ uint8_t color)
+{
+
+ // stupidest version - just pixels - but fast with internal buffer!
+ for (uint8_t i=x; i<x+w; i++) {
+ for (uint8_t j=y; j<y+h; j++) {
+ my_setpixel(i, j, color);
+ }
+ }
+
+ updateBoundingBox(x, y, x+w, y+h);
+}
+
+// draw a rectangle
+void ST7565::drawrect(uint8_t x, uint8_t y, uint8_t w, uint8_t h,
+ uint8_t color)
+{
+ // stupidest version - just pixels - but fast with internal buffer!
+ for (uint8_t i=x; i<x+w; i++) {
+ my_setpixel(i, y, color);
+ my_setpixel(i, y+h-1, color);
+ }
+ for (uint8_t i=y; i<y+h; i++) {
+ my_setpixel(x, i, color);
+ my_setpixel(x+w-1, i, color);
+ }
+
+ updateBoundingBox(x, y, x+w, y+h);
+}
+
+// draw a circle outline
+void ST7565::drawcircle(uint8_t x0, uint8_t y0, uint8_t r,
+ uint8_t color)
+{
+ updateBoundingBox(x0-r, y0-r, x0+r, y0+r);
+
+ int8_t f = 1 - r;
+ int8_t ddF_x = 1;
+ int8_t ddF_y = -2 * r;
+ int8_t x = 0;
+ int8_t y = r;
+
+ my_setpixel(x0, y0+r, color);
+ my_setpixel(x0, y0-r, color);
+ my_setpixel(x0+r, y0, color);
+ my_setpixel(x0-r, y0, color);
+
+ while (x<y) {
+ if (f >= 0) {
+ y--;
+ ddF_y += 2;
+ f += ddF_y;
+ }
+ x++;
+ ddF_x += 2;
+ f += ddF_x;
+
+ my_setpixel(x0 + x, y0 + y, color);
+ my_setpixel(x0 - x, y0 + y, color);
+ my_setpixel(x0 + x, y0 - y, color);
+ my_setpixel(x0 - x, y0 - y, color);
+
+ my_setpixel(x0 + y, y0 + x, color);
+ my_setpixel(x0 - y, y0 + x, color);
+ my_setpixel(x0 + y, y0 - x, color);
+ my_setpixel(x0 - y, y0 - x, color);
+
+ }
+}
+
+void ST7565::fillcircle(uint8_t x0, uint8_t y0, uint8_t r,
+ uint8_t color)
+{
+ updateBoundingBox(x0-r, y0-r, x0+r, y0+r);
+
+ int8_t f = 1 - r;
+ int8_t ddF_x = 1;
+ int8_t ddF_y = -2 * r;
+ int8_t x = 0;
+ int8_t y = r;
+
+ for (uint8_t i=y0-r; i<=y0+r; i++) {
+ my_setpixel(x0, i, color);
+ }
+
+ while (x<y) {
+ if (f >= 0) {
+ y--;
+ ddF_y += 2;
+ f += ddF_y;
+ }
+ x++;
+ ddF_x += 2;
+ f += ddF_x;
+
+ for (uint8_t i=y0-y; i<=y0+y; i++) {
+ my_setpixel(x0+x, i, color);
+ my_setpixel(x0-x, i, color);
+ }
+ for (uint8_t i=y0-x; i<=y0+x; i++) {
+ my_setpixel(x0+y, i, color);
+ my_setpixel(x0-y, i, color);
+ }
+ }
+}
+
+void ST7565::my_setpixel(uint8_t x, uint8_t y, uint8_t color)
+{
+ if ((x >= LCDWIDTH) || (y >= LCDHEIGHT))
+ return;
+
+ // x is which column
+ if (color)
+ st7565_buffer[x+ (y/8)*128] |= _BV(7-(y%8));
+ else
+ st7565_buffer[x+ (y/8)*128] &= _nBV(7-(y%8));
+}
+
+// the most basic function, set a single pixel
+void ST7565::setpixel(uint8_t x, uint8_t y, uint8_t color)
+{
+ if ((x >= LCDWIDTH) || (y >= LCDHEIGHT))
+ return;
+ // x is which column
+ if (color)
+ st7565_buffer[x+ (y/8)*128] |= _BV(7-(y%8));
+ else
+ st7565_buffer[x+ (y/8)*128] &= _nBV(7-(y%8));
+
+ updateBoundingBox(x,y,x,y);
+}
+
+
+// the most basic function, get a single pixel
+uint8_t ST7565::getpixel(uint8_t x, uint8_t y)
+{
+ if ((x >= LCDWIDTH) || (y >= LCDHEIGHT))
+ return 0;
+
+ return (st7565_buffer[x+ (y/8)*128] >> (7-(y%8))) & 0x1;
+}
+
+
+ST7565::ST7565(PinName mosi, PinName sclk, PinName cs, PinName rst, PinName a0)
+// set pin directions
+ : _spi(mosi, NC, sclk), _cs(cs), _rst(rst), _a0(a0)
+
+{
+ _spi.format(8, 0);
+ _spi.frequency(1000000);
+}
+
+
+
+void ST7565::st7565_init(void)
+{
+ wait_ms(100);
+ _rst = 0;
+ wait_ms(100);
+ _rst = 1;
+
+
+ // LCD bias select
+ st7565_command(CMD_SET_BIAS_7);
+ // ADC select
+ st7565_command(CMD_SET_ADC_NORMAL);
+ // SHL select
+ st7565_command(CMD_SET_COM_NORMAL);
+
+ // turn on voltage converter (VC=1, VR=0, VF=0)
+ st7565_command(CMD_SET_POWER_CONTROL | 0x4);
+ // wait for 50% rising
+ wait_ms(50);
+
+ // turn on voltage regulator (VC=1, VR=1, VF=0)
+ st7565_command(CMD_SET_POWER_CONTROL | 0x6);
+ // wait >=50ms
+ wait_ms(20);
+
+ // turn on voltage follower (VC=1, VR=1, VF=1)
+ st7565_command(CMD_SET_POWER_CONTROL | 0x7);
+ // wait
+ wait_ms(10);
+
+ // set lcd operating voltage (regulator resistor, ref voltage resistor)
+ st7565_command(CMD_SET_RESISTOR_RATIO | 0x4);
+ wait_ms(10);
+
+
+// st7565_set_brightness(INITIAL_CONTRAST);
+ // set up a bounding box for screen updates
+ updateBoundingBox(0, 0, LCDWIDTH-1, LCDHEIGHT-1);
+
+
+ st7565_command(CMD_DISPLAY_ON);
+ st7565_command(CMD_SET_ALLPTS_NORMAL);
+
+
+ // reference voltage resistor
+ st7565_command(CMD_SET_VOLUME_FIRST);
+ wait_ms(10);
+ st7565_command(CMD_SET_VOLUME_SECOND);
+ wait_ms(10);
+
+
+
+ // Initial display line ( = 0)
+ st7565_command(CMD_SET_DISP_START_LINE);
+ // Initial page address ( = 0)
+ st7565_command(CMD_SET_PAGE);
+ st7565_command(CMD_SET_COLUMN_UPPER);
+ st7565_command(CMD_SET_COLUMN_LOWER);
+
+}
+
+inline void ST7565::spiwrite(uint8_t c)
+{
+ _spi.write(c);
+}
+
+void ST7565::st7565_command(uint8_t c)
+{
+ _cs = 0;
+ _a0 = 0;
+ _spi.write(c);
+ _cs = 1;
+}
+
+void ST7565::st7565_data(uint8_t c)
+{
+ _cs = 0;
+ _a0 = 1;
+ _spi.write(c);
+ _cs = 1;
+}
+
+void ST7565::st7565_set_brightness(uint8_t val)
+{
+ st7565_command(CMD_SET_VOLUME_FIRST);
+ st7565_command(CMD_SET_VOLUME_SECOND | (val & 0x3f));
+}
+
+void ST7565::begin(uint8_t contrast){
+ st7565_init();
+ st7565_command(CMD_DISPLAY_ON);
+ st7565_command(CMD_SET_ALLPTS_NORMAL);
+ st7565_set_brightness(contrast);
+}
+
+
+void ST7565::display(void)
+{
+ uint8_t col, maxcol, p;
+
+ for(p = 0; p < 8; p++) {
+#ifdef enablePartialUpdate
+ // check if this page is part of update
+ if ( yUpdateMin >= ((p+1)*8) ) {
+ continue; // nope, skip it!
+ }
+ if (yUpdateMax < p*8) {
+ break;
+ }
+#endif
+ st7565_command(CMD_SET_PAGE | pagemap[p]);
+
+#ifdef enablePartialUpdate
+ col = xUpdateMin;
+ maxcol = xUpdateMax;
+#else
+ // start at the beginning of the row
+ col = 0;
+ maxcol = LCDWIDTH-1;
+#endif
+
+ st7565_command(CMD_SET_COLUMN_LOWER | ((col+ST7565_STARTBYTES) & 0xf));
+ st7565_command(CMD_SET_COLUMN_UPPER | (((col+ST7565_STARTBYTES) >> 4) & 0x0F));
+ st7565_command(CMD_RMW);
+
+ for(; col <= maxcol; col++) {
+ st7565_data(st7565_buffer[(128*p)+col]);
+ }
+ }
+
+#ifdef enablePartialUpdate
+ xUpdateMin = LCDWIDTH - 1;
+ xUpdateMax = 0;
+ yUpdateMin = LCDHEIGHT-1;
+ yUpdateMax = 0;
+#endif
+}
+
+// clear everything
+void ST7565::clear(void)
+{
+ memset(st7565_buffer, 0, 1024);
+ updateBoundingBox(0, 0, LCDWIDTH-1, LCDHEIGHT-1);
+}
+
+
+// this doesnt touch the buffer, just clears the display RAM - might be handy
+void ST7565::clear_display(void)
+{
+ uint8_t p, c;
+
+ for(p = 0; p < 8; p++) {
+
+ st7565_command(CMD_SET_PAGE | p);
+ for(c = 0; c < 129; c++) {
+ st7565_command(CMD_SET_COLUMN_LOWER | (c & 0xf));
+ st7565_command(CMD_SET_COLUMN_UPPER | ((c >> 4) & 0xf));
+ st7565_data(0x0);
+ }
+ }
+}
+
+//additional function to set a bit
+uint8_t ST7565::_BV(uint8_t bit)
+{
+ return 1 << bit;
+}
+
+uint8_t ST7565::_nBV(uint8_t bit)
+{
+ return 0 << bit;
+}
\ No newline at end of file
