Simple library for UC1701 based GLCD's

Dependents:   Opensmart_LCD_UC1701

With lots of fonts! Will include more in the future. A couple bitmaps have also been added.

Revision:
0:a8cfaf48d064
Child:
1:f396898c2963
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/UC1701.cpp	Sun Dec 18 21:10:26 2016 +0000
@@ -0,0 +1,210 @@
+/**
+ * This is a simple library for UC1701 controlled graphic LCD's. 
+ * Written for a cheap OPEN-SMART 1.8" 128x64 display
+ * See      http://www.dx.com/p/open-smart-1-8-128-64-lcd-display-breakout-module-w-blue-backlit-444694
+ 
+ * Written by:  Erik van de Coevering
+ * With special thanks to Tim Barr from whom I've reused some code
+ * Use this code in whatever way you like, as long as it stays free of charge!
+ *
+ * Copyright (c) 2016
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * 
+ */
+
+#include "UC1701.h"
+
+UC1701::UC1701(SPI &lcd, DigitalOut &lcd_cs, DigitalOut &lcd_cd)
+{
+    _lcd = &lcd;
+    _lcd_cs = &lcd_cs;
+    _lcd_cd = &lcd_cd;
+}
+
+void UC1701::init()
+{
+    _lcd_cs->write(1);
+    _lcd->frequency(24000000);      // Abusing SPI to save some time.. 
+    _lcd->format(8,3);
+    _lcd_cs->write(0);              // enable SPI
+    _lcd_cd->write(0);                  // COMMAND mode
+
+    wait_ms(50);
+
+    _lcd->write(0xE2);              // Reset
+    _lcd->write(0x40);              // Set display start line to 0
+    _lcd->write(0xA1);              // Set SEG direction
+    _lcd->write(0xC0);              // Set COM direction
+    _lcd->write(0xA2);              // Set bias = 1/9
+    _lcd->write(0x2C);              // Boost ON
+    _lcd->write(0x2E);              // Voltage regulator on
+    _lcd->write(0x2F);              // Voltage follower on
+    _lcd->write(0xF8);              // Set booster ratio
+    _lcd->write(0x00);              // to 4
+    _lcd->write(0x23);              // Set resistor ratio
+    _lcd->write(0x81);              // to 3
+    _lcd->write(0x28);              // Set Electronic volume to 40
+    _lcd->write(0xEE);              // Set cursor update ON -> after write, column cursor will be updated (rows will not!)
+    _lcd->write(0xAC);              // Disable static indicator
+    _lcd->write(0x00);
+    _lcd->write(0xA6);              // Disable inverse
+    _lcd->write(0xAF);              // Display enable
+    //_lcd->write(0xA5);              // display all points
+    _lcd->write(0xA4);              // clear
+    _lcd_cs->write(1);                  // disable SPI
+    _lcd_cd->write(1);                  // DATA mode
+
+}
+
+void UC1701::setCursor(char column, char line)
+{
+    int i, j;
+    column = column+4;
+
+    i=(column&0xF0)>>4;
+    j=column&0x0F;
+    _lcd_cd->write(0);
+    _lcd->write(0xb0+line);
+    _lcd->write(0x10+i);
+    _lcd->write(j);
+    _lcd_cd->write(1);
+}
+
+void UC1701::clear()
+{
+    _lcd_cs->write(0);
+    _lcd_cd->write(1);
+
+    for(unsigned short j = 0; j < 8; j++) {
+        UC1701::setCursor(0, j);
+        for(unsigned short i = 0; i < 128 ; i++) {
+            _lcd->write(0x00);
+        }
+    }
+
+    UC1701::setCursor(0, 0);
+
+    _lcd_cs->write(1);
+}
+
+// fill() only used to optimize the library. Using command 0xA5 is faster, if needed.
+void UC1701::fill()
+{
+    _lcd_cs->write(0);
+    _lcd_cd->write(1);
+
+    for(unsigned short j = 0; j < 8; j++) {
+        UC1701::setCursor(0, j);
+        for(unsigned short i = 0; i < 128 ; i++) {
+            _lcd->write(0xFF);
+        }
+    }
+
+    UC1701::setCursor(0, 0);
+
+    _lcd_cs->write(1);
+}
+
+void UC1701::writeText2d(char column, char page, const char font_address[96][8], const char *text, int size)
+{
+    _lcd_cs->write(0);
+    UC1701::setCursor(column, page);
+    for(int i=0; i<=size; i++) {
+        for(int a=0; a<8; a++) {
+            _lcd->write((font_address[(text[i]-32)][a]));
+        }
+    }
+    _lcd_cs->write(1);
+}
+
+void UC1701::writeText(char column, char page, const char *font_address, const char *text, const uint8_t size)
+{
+    // Position of character data in memory array
+    uint16_t pos_array;
+    // temporary column, page address, and column_cnt are used
+    // to stay inside display area
+    uint8_t i,y, column_cnt = 0;
+    uint8_t count = 0;
+
+    // font information, needed for calculation
+    uint8_t start_code, last_code, width, page_height, bytes_p_char;
+
+    uint8_t *txtbuffer;
+
+    start_code   = font_address[2];  // get first defined character
+    last_code    = font_address[3];  // get last defined character
+    width        = font_address[4];  // width in pixel of one char
+    page_height  = font_address[6];  // page count per char
+    bytes_p_char = font_address[7];  // bytes per char
+
+    _lcd_cs->write(0);  // Enable SPI
+    _lcd_cd->write(1);  // Data mode
+
+    if(page_height + page > LCDPAGES) //stay inside display area
+        page_height = LCDPAGES - page;
+
+    // The string is displayed character after character. If the font has more then one page,
+    // the top page is printed first, then the next page and so on
+    for(y = 0; y < page_height; y++) {
+        txtbuffer = &_lcdbuffer[page*LCDWIDTH + column];
+        column_cnt = 0;                 // clear column_cnt start point
+        i = 0;
+        while(( i < size) && ((column_cnt + column) < LCDWIDTH)) {
+            if(text[i] < start_code || (uint8_t)text[i] > last_code) //make sure data is valid
+                i++;
+            else {
+                // calculate position of ASCII character in font array
+                // bytes for header + (ASCII - startcode) * bytes per char)
+                pos_array = 8 + (uint8_t)(text[i++] - start_code) * bytes_p_char;
+
+                // get the dot pattern for the part of the char to print
+                pos_array += y*width;
+
+                // stay inside display area
+                if((column_cnt + width + column) > LCDWIDTH)
+                    column_cnt = LCDWIDTH-width;
+
+                // copy character data to buffer
+                memcpy (txtbuffer+column_cnt,font_address+pos_array,width);
+            }
+
+            column_cnt += width;
+        }
+        UC1701::setCursor(column,page);  // set start position x and y
+
+        do {
+            _lcd->write(txtbuffer[count]);
+            count++;
+        } while ((count <= column_cnt));
+    }
+
+    _lcd_cs->write(1);  // Disable SPI
+
+}
+
+void UC1701::drawBitmap(const char *data)
+{
+    int cnt = 0;
+    _lcd_cs->write(0);
+    _lcd_cd->write(1);
+    UC1701::setCursor(0,0);
+    for(int row=0; row<8; row++) {
+        UC1701::setCursor(0, row);
+        for(int column=0; column<128; column++) {
+            _lcd->write(data[cnt]);
+            cnt++;
+        }
+    }
+}
\ No newline at end of file