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.

Committer:
Anaesthetix
Date:
Sun Dec 18 21:12:40 2016 +0000
Revision:
1:f396898c2963
Parent:
0:a8cfaf48d064
Child:
3:baaa16e24adc
Added header

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Anaesthetix 0:a8cfaf48d064 1 /**
Anaesthetix 0:a8cfaf48d064 2 * This is a simple library for UC1701 controlled graphic LCD's.
Anaesthetix 0:a8cfaf48d064 3 * Written for a cheap OPEN-SMART 1.8" 128x64 display
Anaesthetix 0:a8cfaf48d064 4 * See http://www.dx.com/p/open-smart-1-8-128-64-lcd-display-breakout-module-w-blue-backlit-444694
Anaesthetix 1:f396898c2963 5 *
Anaesthetix 0:a8cfaf48d064 6 * Written by: Erik van de Coevering
Anaesthetix 0:a8cfaf48d064 7 * With special thanks to Tim Barr from whom I've reused some code
Anaesthetix 0:a8cfaf48d064 8 * Use this code in whatever way you like, as long as it stays free of charge!
Anaesthetix 0:a8cfaf48d064 9 */
Anaesthetix 0:a8cfaf48d064 10
Anaesthetix 0:a8cfaf48d064 11 #include "UC1701.h"
Anaesthetix 0:a8cfaf48d064 12
Anaesthetix 0:a8cfaf48d064 13 UC1701::UC1701(SPI &lcd, DigitalOut &lcd_cs, DigitalOut &lcd_cd)
Anaesthetix 0:a8cfaf48d064 14 {
Anaesthetix 0:a8cfaf48d064 15 _lcd = &lcd;
Anaesthetix 0:a8cfaf48d064 16 _lcd_cs = &lcd_cs;
Anaesthetix 0:a8cfaf48d064 17 _lcd_cd = &lcd_cd;
Anaesthetix 0:a8cfaf48d064 18 }
Anaesthetix 0:a8cfaf48d064 19
Anaesthetix 0:a8cfaf48d064 20 void UC1701::init()
Anaesthetix 0:a8cfaf48d064 21 {
Anaesthetix 0:a8cfaf48d064 22 _lcd_cs->write(1);
Anaesthetix 0:a8cfaf48d064 23 _lcd->frequency(24000000); // Abusing SPI to save some time..
Anaesthetix 0:a8cfaf48d064 24 _lcd->format(8,3);
Anaesthetix 0:a8cfaf48d064 25 _lcd_cs->write(0); // enable SPI
Anaesthetix 0:a8cfaf48d064 26 _lcd_cd->write(0); // COMMAND mode
Anaesthetix 0:a8cfaf48d064 27
Anaesthetix 0:a8cfaf48d064 28 wait_ms(50);
Anaesthetix 0:a8cfaf48d064 29
Anaesthetix 0:a8cfaf48d064 30 _lcd->write(0xE2); // Reset
Anaesthetix 0:a8cfaf48d064 31 _lcd->write(0x40); // Set display start line to 0
Anaesthetix 0:a8cfaf48d064 32 _lcd->write(0xA1); // Set SEG direction
Anaesthetix 0:a8cfaf48d064 33 _lcd->write(0xC0); // Set COM direction
Anaesthetix 0:a8cfaf48d064 34 _lcd->write(0xA2); // Set bias = 1/9
Anaesthetix 0:a8cfaf48d064 35 _lcd->write(0x2C); // Boost ON
Anaesthetix 0:a8cfaf48d064 36 _lcd->write(0x2E); // Voltage regulator on
Anaesthetix 0:a8cfaf48d064 37 _lcd->write(0x2F); // Voltage follower on
Anaesthetix 0:a8cfaf48d064 38 _lcd->write(0xF8); // Set booster ratio
Anaesthetix 0:a8cfaf48d064 39 _lcd->write(0x00); // to 4
Anaesthetix 0:a8cfaf48d064 40 _lcd->write(0x23); // Set resistor ratio
Anaesthetix 0:a8cfaf48d064 41 _lcd->write(0x81); // to 3
Anaesthetix 0:a8cfaf48d064 42 _lcd->write(0x28); // Set Electronic volume to 40
Anaesthetix 0:a8cfaf48d064 43 _lcd->write(0xEE); // Set cursor update ON -> after write, column cursor will be updated (rows will not!)
Anaesthetix 0:a8cfaf48d064 44 _lcd->write(0xAC); // Disable static indicator
Anaesthetix 0:a8cfaf48d064 45 _lcd->write(0x00);
Anaesthetix 0:a8cfaf48d064 46 _lcd->write(0xA6); // Disable inverse
Anaesthetix 0:a8cfaf48d064 47 _lcd->write(0xAF); // Display enable
Anaesthetix 0:a8cfaf48d064 48 //_lcd->write(0xA5); // display all points
Anaesthetix 0:a8cfaf48d064 49 _lcd->write(0xA4); // clear
Anaesthetix 0:a8cfaf48d064 50 _lcd_cs->write(1); // disable SPI
Anaesthetix 0:a8cfaf48d064 51 _lcd_cd->write(1); // DATA mode
Anaesthetix 0:a8cfaf48d064 52
Anaesthetix 0:a8cfaf48d064 53 }
Anaesthetix 0:a8cfaf48d064 54
Anaesthetix 0:a8cfaf48d064 55 void UC1701::setCursor(char column, char line)
Anaesthetix 0:a8cfaf48d064 56 {
Anaesthetix 0:a8cfaf48d064 57 int i, j;
Anaesthetix 0:a8cfaf48d064 58 column = column+4;
Anaesthetix 0:a8cfaf48d064 59
Anaesthetix 0:a8cfaf48d064 60 i=(column&0xF0)>>4;
Anaesthetix 0:a8cfaf48d064 61 j=column&0x0F;
Anaesthetix 0:a8cfaf48d064 62 _lcd_cd->write(0);
Anaesthetix 0:a8cfaf48d064 63 _lcd->write(0xb0+line);
Anaesthetix 0:a8cfaf48d064 64 _lcd->write(0x10+i);
Anaesthetix 0:a8cfaf48d064 65 _lcd->write(j);
Anaesthetix 0:a8cfaf48d064 66 _lcd_cd->write(1);
Anaesthetix 0:a8cfaf48d064 67 }
Anaesthetix 0:a8cfaf48d064 68
Anaesthetix 0:a8cfaf48d064 69 void UC1701::clear()
Anaesthetix 0:a8cfaf48d064 70 {
Anaesthetix 0:a8cfaf48d064 71 _lcd_cs->write(0);
Anaesthetix 0:a8cfaf48d064 72 _lcd_cd->write(1);
Anaesthetix 0:a8cfaf48d064 73
Anaesthetix 0:a8cfaf48d064 74 for(unsigned short j = 0; j < 8; j++) {
Anaesthetix 0:a8cfaf48d064 75 UC1701::setCursor(0, j);
Anaesthetix 0:a8cfaf48d064 76 for(unsigned short i = 0; i < 128 ; i++) {
Anaesthetix 0:a8cfaf48d064 77 _lcd->write(0x00);
Anaesthetix 0:a8cfaf48d064 78 }
Anaesthetix 0:a8cfaf48d064 79 }
Anaesthetix 0:a8cfaf48d064 80
Anaesthetix 0:a8cfaf48d064 81 UC1701::setCursor(0, 0);
Anaesthetix 0:a8cfaf48d064 82
Anaesthetix 0:a8cfaf48d064 83 _lcd_cs->write(1);
Anaesthetix 0:a8cfaf48d064 84 }
Anaesthetix 0:a8cfaf48d064 85
Anaesthetix 0:a8cfaf48d064 86 // fill() only used to optimize the library. Using command 0xA5 is faster, if needed.
Anaesthetix 0:a8cfaf48d064 87 void UC1701::fill()
Anaesthetix 0:a8cfaf48d064 88 {
Anaesthetix 0:a8cfaf48d064 89 _lcd_cs->write(0);
Anaesthetix 0:a8cfaf48d064 90 _lcd_cd->write(1);
Anaesthetix 0:a8cfaf48d064 91
Anaesthetix 0:a8cfaf48d064 92 for(unsigned short j = 0; j < 8; j++) {
Anaesthetix 0:a8cfaf48d064 93 UC1701::setCursor(0, j);
Anaesthetix 0:a8cfaf48d064 94 for(unsigned short i = 0; i < 128 ; i++) {
Anaesthetix 0:a8cfaf48d064 95 _lcd->write(0xFF);
Anaesthetix 0:a8cfaf48d064 96 }
Anaesthetix 0:a8cfaf48d064 97 }
Anaesthetix 0:a8cfaf48d064 98
Anaesthetix 0:a8cfaf48d064 99 UC1701::setCursor(0, 0);
Anaesthetix 0:a8cfaf48d064 100
Anaesthetix 0:a8cfaf48d064 101 _lcd_cs->write(1);
Anaesthetix 0:a8cfaf48d064 102 }
Anaesthetix 0:a8cfaf48d064 103
Anaesthetix 0:a8cfaf48d064 104 void UC1701::writeText2d(char column, char page, const char font_address[96][8], const char *text, int size)
Anaesthetix 0:a8cfaf48d064 105 {
Anaesthetix 0:a8cfaf48d064 106 _lcd_cs->write(0);
Anaesthetix 0:a8cfaf48d064 107 UC1701::setCursor(column, page);
Anaesthetix 0:a8cfaf48d064 108 for(int i=0; i<=size; i++) {
Anaesthetix 0:a8cfaf48d064 109 for(int a=0; a<8; a++) {
Anaesthetix 0:a8cfaf48d064 110 _lcd->write((font_address[(text[i]-32)][a]));
Anaesthetix 0:a8cfaf48d064 111 }
Anaesthetix 0:a8cfaf48d064 112 }
Anaesthetix 0:a8cfaf48d064 113 _lcd_cs->write(1);
Anaesthetix 0:a8cfaf48d064 114 }
Anaesthetix 0:a8cfaf48d064 115
Anaesthetix 0:a8cfaf48d064 116 void UC1701::writeText(char column, char page, const char *font_address, const char *text, const uint8_t size)
Anaesthetix 0:a8cfaf48d064 117 {
Anaesthetix 0:a8cfaf48d064 118 // Position of character data in memory array
Anaesthetix 0:a8cfaf48d064 119 uint16_t pos_array;
Anaesthetix 0:a8cfaf48d064 120 // temporary column, page address, and column_cnt are used
Anaesthetix 0:a8cfaf48d064 121 // to stay inside display area
Anaesthetix 0:a8cfaf48d064 122 uint8_t i,y, column_cnt = 0;
Anaesthetix 0:a8cfaf48d064 123 uint8_t count = 0;
Anaesthetix 0:a8cfaf48d064 124
Anaesthetix 0:a8cfaf48d064 125 // font information, needed for calculation
Anaesthetix 0:a8cfaf48d064 126 uint8_t start_code, last_code, width, page_height, bytes_p_char;
Anaesthetix 0:a8cfaf48d064 127
Anaesthetix 0:a8cfaf48d064 128 uint8_t *txtbuffer;
Anaesthetix 0:a8cfaf48d064 129
Anaesthetix 0:a8cfaf48d064 130 start_code = font_address[2]; // get first defined character
Anaesthetix 0:a8cfaf48d064 131 last_code = font_address[3]; // get last defined character
Anaesthetix 0:a8cfaf48d064 132 width = font_address[4]; // width in pixel of one char
Anaesthetix 0:a8cfaf48d064 133 page_height = font_address[6]; // page count per char
Anaesthetix 0:a8cfaf48d064 134 bytes_p_char = font_address[7]; // bytes per char
Anaesthetix 0:a8cfaf48d064 135
Anaesthetix 0:a8cfaf48d064 136 _lcd_cs->write(0); // Enable SPI
Anaesthetix 0:a8cfaf48d064 137 _lcd_cd->write(1); // Data mode
Anaesthetix 0:a8cfaf48d064 138
Anaesthetix 0:a8cfaf48d064 139 if(page_height + page > LCDPAGES) //stay inside display area
Anaesthetix 0:a8cfaf48d064 140 page_height = LCDPAGES - page;
Anaesthetix 0:a8cfaf48d064 141
Anaesthetix 0:a8cfaf48d064 142 // The string is displayed character after character. If the font has more then one page,
Anaesthetix 0:a8cfaf48d064 143 // the top page is printed first, then the next page and so on
Anaesthetix 0:a8cfaf48d064 144 for(y = 0; y < page_height; y++) {
Anaesthetix 0:a8cfaf48d064 145 txtbuffer = &_lcdbuffer[page*LCDWIDTH + column];
Anaesthetix 0:a8cfaf48d064 146 column_cnt = 0; // clear column_cnt start point
Anaesthetix 0:a8cfaf48d064 147 i = 0;
Anaesthetix 0:a8cfaf48d064 148 while(( i < size) && ((column_cnt + column) < LCDWIDTH)) {
Anaesthetix 0:a8cfaf48d064 149 if(text[i] < start_code || (uint8_t)text[i] > last_code) //make sure data is valid
Anaesthetix 0:a8cfaf48d064 150 i++;
Anaesthetix 0:a8cfaf48d064 151 else {
Anaesthetix 0:a8cfaf48d064 152 // calculate position of ASCII character in font array
Anaesthetix 0:a8cfaf48d064 153 // bytes for header + (ASCII - startcode) * bytes per char)
Anaesthetix 0:a8cfaf48d064 154 pos_array = 8 + (uint8_t)(text[i++] - start_code) * bytes_p_char;
Anaesthetix 0:a8cfaf48d064 155
Anaesthetix 0:a8cfaf48d064 156 // get the dot pattern for the part of the char to print
Anaesthetix 0:a8cfaf48d064 157 pos_array += y*width;
Anaesthetix 0:a8cfaf48d064 158
Anaesthetix 0:a8cfaf48d064 159 // stay inside display area
Anaesthetix 0:a8cfaf48d064 160 if((column_cnt + width + column) > LCDWIDTH)
Anaesthetix 0:a8cfaf48d064 161 column_cnt = LCDWIDTH-width;
Anaesthetix 0:a8cfaf48d064 162
Anaesthetix 0:a8cfaf48d064 163 // copy character data to buffer
Anaesthetix 0:a8cfaf48d064 164 memcpy (txtbuffer+column_cnt,font_address+pos_array,width);
Anaesthetix 0:a8cfaf48d064 165 }
Anaesthetix 0:a8cfaf48d064 166
Anaesthetix 0:a8cfaf48d064 167 column_cnt += width;
Anaesthetix 0:a8cfaf48d064 168 }
Anaesthetix 0:a8cfaf48d064 169 UC1701::setCursor(column,page); // set start position x and y
Anaesthetix 0:a8cfaf48d064 170
Anaesthetix 0:a8cfaf48d064 171 do {
Anaesthetix 0:a8cfaf48d064 172 _lcd->write(txtbuffer[count]);
Anaesthetix 0:a8cfaf48d064 173 count++;
Anaesthetix 0:a8cfaf48d064 174 } while ((count <= column_cnt));
Anaesthetix 0:a8cfaf48d064 175 }
Anaesthetix 0:a8cfaf48d064 176
Anaesthetix 0:a8cfaf48d064 177 _lcd_cs->write(1); // Disable SPI
Anaesthetix 0:a8cfaf48d064 178
Anaesthetix 0:a8cfaf48d064 179 }
Anaesthetix 0:a8cfaf48d064 180
Anaesthetix 0:a8cfaf48d064 181 void UC1701::drawBitmap(const char *data)
Anaesthetix 0:a8cfaf48d064 182 {
Anaesthetix 0:a8cfaf48d064 183 int cnt = 0;
Anaesthetix 0:a8cfaf48d064 184 _lcd_cs->write(0);
Anaesthetix 0:a8cfaf48d064 185 _lcd_cd->write(1);
Anaesthetix 0:a8cfaf48d064 186 UC1701::setCursor(0,0);
Anaesthetix 0:a8cfaf48d064 187 for(int row=0; row<8; row++) {
Anaesthetix 0:a8cfaf48d064 188 UC1701::setCursor(0, row);
Anaesthetix 0:a8cfaf48d064 189 for(int column=0; column<128; column++) {
Anaesthetix 0:a8cfaf48d064 190 _lcd->write(data[cnt]);
Anaesthetix 0:a8cfaf48d064 191 cnt++;
Anaesthetix 0:a8cfaf48d064 192 }
Anaesthetix 0:a8cfaf48d064 193 }
Anaesthetix 0:a8cfaf48d064 194 }