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.
Diff: UC1701.cpp
- 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