Text console library for ST7565 graphics LCD controller over SPI interface.
Dependents: TextLCD_ST7565SPI_Test OpPanel_Offline OpPanel_Offline_cmake_gcc_arm_NUCLEO_F303RENew
TextLCD_ST7565SPI.cpp
00001 // ==================================================== Mar 03 2015, kayeks == 00002 // TextLCD_ST7565SPI.cpp 00003 // =========================================================================== 00004 // Text console library for ST7565 graphics LCD controller over SPI interface. 00005 00006 #include <string.h> 00007 #include "TextLCD_ST7565SPI.h" 00008 00009 const uint8_t TextLCD_ST7565SPI::FONT_5X7[128][5] = { 00010 // 00h..07h 00011 { 0x77, 0x55, 0x55, 0x55, 0x77 }, // unimplemented NUL 00012 { 0x77, 0x52, 0x52, 0x52, 0x76 }, // unimplemented SOH 00013 { 0x77, 0x54, 0x57, 0x51, 0x77 }, // unimplemented STX 00014 { 0x77, 0x51, 0x56, 0x51, 0x77 }, // unimplemented ETX 00015 { 0x71, 0x57, 0x55, 0x55, 0x71 }, // unimplemented EOT 00016 { 0x77, 0x51, 0x57, 0x54, 0x77 }, // unimplemented ENQ 00017 { 0x77, 0x55, 0x57, 0x54, 0x77 }, // unimplemented ACK 00018 { 0x74, 0x54, 0x52, 0x51, 0x77 }, // unimplemented BEL 00019 // 08h..0Fh 00020 { 0x77, 0x55, 0x57, 0x55, 0x77 }, // unimplemented BS 00021 { 0x77, 0x51, 0x57, 0x55, 0x77 }, // unimplemented HT 00022 { 0x75, 0x57, 0x55, 0x55, 0x77 }, // unimplemented LF 00023 { 0x77, 0x55, 0x55, 0x57, 0x74 }, // unimplemented VT 00024 { 0x77, 0x54, 0x54, 0x54, 0x77 }, // unimplemented FF 00025 { 0x77, 0x55, 0x55, 0x57, 0x71 }, // unimplemented CR 00026 { 0x77, 0x54, 0x57, 0x54, 0x77 }, // unimplemented SO 00027 { 0x74, 0x54, 0x57, 0x54, 0x77 }, // unimplemented SI 00028 // 10h..17h 00029 { 0x77, 0x25, 0x25, 0x25, 0x67 }, // unimplemented DLE 00030 { 0x77, 0x22, 0x22, 0x22, 0x66 }, // unimplemented DC1 00031 { 0x77, 0x24, 0x27, 0x21, 0x67 }, // unimplemented DC2 00032 { 0x77, 0x21, 0x26, 0x21, 0x67 }, // unimplemented DC3 00033 { 0x71, 0x27, 0x25, 0x25, 0x61 }, // unimplemented DC4 00034 { 0x77, 0x21, 0x27, 0x24, 0x67 }, // unimplemented NAK 00035 { 0x77, 0x25, 0x27, 0x24, 0x67 }, // unimplemented SYN 00036 { 0x74, 0x24, 0x22, 0x21, 0x67 }, // unimplemented ETB 00037 // 18h..1Fh 00038 { 0x77, 0x25, 0x27, 0x25, 0x67 }, // unimplemented CAN 00039 { 0x77, 0x21, 0x27, 0x25, 0x67 }, // unimplemented EM 00040 { 0x75, 0x27, 0x25, 0x25, 0x67 }, // unimplemented SUB 00041 { 0x77, 0x25, 0x25, 0x27, 0x64 }, // unimplemented ESC 00042 { 0x77, 0x24, 0x24, 0x24, 0x67 }, // unimplemented FS 00043 { 0x77, 0x25, 0x25, 0x27, 0x61 }, // unimplemented GS 00044 { 0x77, 0x24, 0x27, 0x24, 0x67 }, // unimplemented RS 00045 { 0x74, 0x24, 0x27, 0x24, 0x67 }, // unimplemented US 00046 // 20h..27h 00047 { 0x00, 0x00, 0x00, 0x00, 0x00 }, // SPC 00048 { 0x00, 0x00, 0x7d, 0x00, 0x00 }, // ! 00049 { 0x00, 0x60, 0x00, 0x60, 0x00 }, // " 00050 { 0x22, 0x7f, 0x22, 0x7f, 0x22 }, // # 00051 { 0x32, 0x49, 0x7f, 0x49, 0x26 }, // $ 00052 { 0x72, 0x54, 0x7f, 0x15, 0x27 }, // % 00053 { 0x36, 0x49, 0x75, 0x02, 0x0d }, // & 00054 { 0x00, 0x20, 0x40, 0x00, 0x00 }, // ' 00055 // 28h..2Fh 00056 { 0x00, 0x00, 0x00, 0x3e, 0x41 }, // ( 00057 { 0x41, 0x3e, 0x00, 0x00, 0x00 }, // ) 00058 { 0x14, 0x08, 0x3e, 0x08, 0x14 }, // * 00059 { 0x08, 0x08, 0x3e, 0x08, 0x08 }, // + 00060 { 0x00, 0x01, 0x02, 0x00, 0x00 }, // , 00061 { 0x08, 0x08, 0x08, 0x08, 0x08 }, // - 00062 { 0x00, 0x00, 0x01, 0x00, 0x00 }, // . 00063 { 0x00, 0x03, 0x1c, 0x60, 0x00 }, // / 00064 // 30h..37h 00065 { 0x3e, 0x41, 0x49, 0x41, 0x3e }, // 0 00066 { 0x00, 0x41, 0x7f, 0x01, 0x00 }, // 1 00067 { 0x27, 0x49, 0x49, 0x49, 0x31 }, // 2 00068 { 0x42, 0x41, 0x51, 0x51, 0x6e }, // 3 00069 { 0x0e, 0x12, 0x22, 0x7f, 0x02 }, // 4 00070 { 0x72, 0x51, 0x51, 0x51, 0x4e }, // 5 00071 { 0x3e, 0x51, 0x51, 0x51, 0x0e }, // 6 00072 { 0x40, 0x40, 0x47, 0x58, 0x60 }, // 7 00073 // 38h..3Fh 00074 { 0x36, 0x49, 0x49, 0x49, 0x36 }, // 8 00075 { 0x38, 0x45, 0x45, 0x45, 0x3e }, // 9 00076 { 0x00, 0x00, 0x12, 0x00, 0x00 }, // : 00077 { 0x00, 0x01, 0x12, 0x00, 0x00 }, // ; 00078 { 0x00, 0x08, 0x14, 0x22, 0x41 }, // < 00079 { 0x14, 0x14, 0x14, 0x14, 0x14 }, // = 00080 { 0x41, 0x22, 0x14, 0x08, 0x00 }, // > 00081 { 0x20, 0x40, 0x45, 0x48, 0x30 }, // ? 00082 // 40h..47h 00083 { 0x3e, 0x41, 0x5d, 0x55, 0x3c }, // @ 00084 { 0x0f, 0x34, 0x44, 0x34, 0x0f }, // A 00085 { 0x7f, 0x49, 0x49, 0x49, 0x36 }, // B 00086 { 0x3e, 0x41, 0x41, 0x41, 0x22 }, // C 00087 { 0x7f, 0x41, 0x41, 0x41, 0x3e }, // D 00088 { 0x7f, 0x49, 0x49, 0x49, 0x41 }, // E 00089 { 0x7f, 0x48, 0x48, 0x48, 0x40 }, // F 00090 { 0x3e, 0x41, 0x49, 0x49, 0x2e }, // G 00091 // 48h..4Fh 00092 { 0x7f, 0x08, 0x08, 0x08, 0x7f }, // H 00093 { 0x00, 0x41, 0x7f, 0x41, 0x00 }, // I 00094 { 0x02, 0x01, 0x01, 0x41, 0x7e }, // J 00095 { 0x7f, 0x08, 0x14, 0x22, 0x41 }, // K 00096 { 0x7f, 0x01, 0x01, 0x01, 0x01 }, // L 00097 { 0x7f, 0x20, 0x1c, 0x20, 0x7f }, // M 00098 { 0x7f, 0x20, 0x10, 0x08, 0x7f }, // N 00099 { 0x3e, 0x41, 0x41, 0x41, 0x3e }, // O 00100 // 50h..57h 00101 { 0x7f, 0x48, 0x48, 0x48, 0x30 }, // P 00102 { 0x3e, 0x41, 0x45, 0x42, 0x3d }, // Q 00103 { 0x7f, 0x48, 0x4c, 0x4a, 0x31 }, // R 00104 { 0x32, 0x49, 0x49, 0x49, 0x26 }, // S 00105 { 0x40, 0x40, 0x7f, 0x40, 0x40 }, // T 00106 { 0x7e, 0x01, 0x01, 0x01, 0x7e }, // U 00107 { 0x78, 0x06, 0x01, 0x06, 0x78 }, // V 00108 { 0x7e, 0x01, 0x1e, 0x01, 0x7e }, // W 00109 // 58h..5Fh 00110 { 0x63, 0x14, 0x08, 0x14, 0x63 }, // X 00111 { 0x60, 0x10, 0x0f, 0x10, 0x60 }, // Y 00112 { 0x43, 0x45, 0x49, 0x51, 0x61 }, // Z 00113 { 0x00, 0x00, 0x00, 0x7f, 0x41 }, // [ 00114 { 0x00, 0x60, 0x1c, 0x03, 0x00 }, // backslash 00115 { 0x41, 0x7f, 0x00, 0x00, 0x00 }, // ] 00116 { 0x00, 0x20, 0x40, 0x20, 0x00 }, // ^ 00117 { 0x01, 0x01, 0x01, 0x01, 0x01 }, // _ 00118 // 60h..67h 00119 { 0x00, 0x00, 0x40, 0x20, 0x00 }, // ` 00120 { 0x02, 0x15, 0x15, 0x15, 0x0f }, // a 00121 { 0x7f, 0x11, 0x11, 0x11, 0x0e }, // b 00122 { 0x0e, 0x11, 0x11, 0x11, 0x0a }, // c 00123 { 0x0e, 0x11, 0x11, 0x11, 0x7f }, // d 00124 { 0x0e, 0x15, 0x15, 0x15, 0x0c }, // e 00125 { 0x00, 0x08, 0x3f, 0x48, 0x48 }, // f 00126 { 0x08, 0x15, 0x15, 0x15, 0x1e }, // g 00127 // 68h..6Fh 00128 { 0x7f, 0x10, 0x10, 0x10, 0x0f }, // h 00129 { 0x00, 0x10, 0x5f, 0x00, 0x00 }, // i 00130 { 0x01, 0x11, 0x5e, 0x00, 0x00 }, // j 00131 { 0x00, 0x7f, 0x04, 0x0a, 0x11 }, // k 00132 { 0x00, 0x40, 0x7f, 0x00, 0x00 }, // l 00133 { 0x1f, 0x10, 0x1f, 0x10, 0x0f }, // m 00134 { 0x1f, 0x10, 0x10, 0x10, 0x0f }, // n 00135 { 0x0e, 0x11, 0x11, 0x11, 0x0e }, // o 00136 // 70h..77h 00137 { 0x1f, 0x12, 0x12, 0x12, 0x0c }, // p 00138 { 0x0c, 0x12, 0x12, 0x12, 0x1f }, // q 00139 { 0x1f, 0x08, 0x10, 0x10, 0x10 }, // r 00140 { 0x09, 0x15, 0x15, 0x15, 0x12 }, // s 00141 { 0x00, 0x3e, 0x11, 0x11, 0x00 }, // t 00142 { 0x1e, 0x01, 0x01, 0x01, 0x1f }, // u 00143 { 0x18, 0x06, 0x01, 0x06, 0x18 }, // v 00144 { 0x1e, 0x01, 0x0e, 0x01, 0x1e }, // w 00145 // 78h..7Fh 00146 { 0x11, 0x0a, 0x04, 0x0a, 0x11 }, // x 00147 { 0x18, 0x05, 0x05, 0x05, 0x1e }, // y 00148 { 0x11, 0x13, 0x15, 0x19, 0x11 }, // z 00149 { 0x00, 0x00, 0x08, 0x7f, 0x41 }, // { 00150 { 0x00, 0x00, 0x7f, 0x00, 0x00 }, // | 00151 { 0x41, 0x7f, 0x08, 0x00, 0x00 }, // } 00152 { 0x08, 0x10, 0x18, 0x08, 0x10 }, // ~ 00153 { 0x44, 0x44, 0x77, 0x44, 0x77 } // unimplemented DEL 00154 }; 00155 00156 TextLCD_ST7565SPI::TextLCD_ST7565SPI(PinName mosi, PinName sck, PinName cs, 00157 PinName rs, PinName rst, 00158 uint8_t columns, uint8_t rows) 00159 : 00160 _rs(rs), 00161 _rst(rst), 00162 _spi(mosi, NC, sck), 00163 _cs(cs) 00164 { 00165 // Allocate line buffer 00166 _columns = columns; 00167 _rows = rows; 00168 _lineBuffer = new uint8_t*[_rows]; 00169 for (uint8_t i = 0; i < _rows; i++) { 00170 _lineBuffer[i] = new uint8_t[_columns]; 00171 } 00172 00173 // Initialize SPI 00174 _spi.format(8, 0); 00175 00176 // Initialize pins 00177 _rs = 0; 00178 _rst = 1; 00179 _cs = 1; 00180 00181 reset(); 00182 } 00183 00184 TextLCD_ST7565SPI::~TextLCD_ST7565SPI() { 00185 for (uint8_t i = 0; i < _rows; i++) { 00186 delete[] _lineBuffer[i]; 00187 } 00188 delete[] _lineBuffer; 00189 } 00190 00191 void TextLCD_ST7565SPI::reset() { 00192 wait_ms(10); 00193 _rst = 0; 00194 wait_ms(10); 00195 _rst = 1; 00196 } 00197 00198 void TextLCD_ST7565SPI::clear() { 00199 for (uint8_t j = 7; j <= 7; j--) { 00200 setPage(j); 00201 setColumn(0); 00202 for (uint8_t i = 0; i < 132; i++) { 00203 data(0x00); 00204 } 00205 } 00206 } 00207 00208 void TextLCD_ST7565SPI::init(uint8_t v0, uint8_t contrast, Bias bias) { 00209 command(INTERNAL_RESET); 00210 wait_ms(5); 00211 00212 command(DISPLAY_ON); 00213 command(PCTRL_BOOSTER_ON | PCTRL_REGULATOR_ON | PCTRL_VFOLLOWER_ON); 00214 command(V0_INTERNAL_R_0 + (v0 & 0x07)); 00215 command(ELECTRONIC_VOL_MODE); 00216 if (contrast == 0) { 00217 contrast = 1; 00218 } 00219 command(ELECTRONIC_VOL_1 - 1 + (contrast & 0x3f)); 00220 switch (bias) { 00221 case Bias1_7: 00222 command(BIAS_1_7); 00223 break; 00224 case Bias1_9: 00225 command(BIAS_1_9); 00226 } 00227 command(COMMON_ASCENDING); 00228 command(SEGMENT_ASCENDING); 00229 command(ENTIRE_DISPLAY_OFF); 00230 command(INVERT_DISPLAY_OFF); 00231 command(COMMON_OFFSET); 00232 cls(); 00233 } 00234 00235 void TextLCD_ST7565SPI::cls() { 00236 clear(); 00237 for (uint8_t j = 0; j < _rows; j++) { 00238 memset(_lineBuffer[j], ' ', _columns); 00239 } 00240 _column = 0; 00241 _row = 0; 00242 } 00243 00244 void TextLCD_ST7565SPI::locate(uint8_t column, uint8_t row) { 00245 if (column < _columns && row < _rows) { 00246 setPage(_rows - row - 1); 00247 setColumn(6 * column); 00248 _column = column; 00249 _row = row; 00250 } 00251 } 00252 00253 int TextLCD_ST7565SPI::_putc(int c) { 00254 switch (c) { 00255 case '\r': // Carriage return 00256 _column = 0; 00257 locate(_column, _row); 00258 break; 00259 case '\n': // Line feed 00260 if (_row == _rows - 1) { 00261 shiftUp(); 00262 } else { 00263 _row++; 00264 } 00265 break; 00266 case '\f': // Form feed 00267 // Clear screen 00268 cls(); 00269 break; 00270 default: 00271 // Break line if the cursor reaches end 00272 if (_column == _columns) { 00273 if (_row == _rows - 1) { 00274 shiftUp(); 00275 } else { 00276 _row++; 00277 } 00278 _column = 0; 00279 } 00280 locate(_column, _row); 00281 for (uint8_t k = 0; k < 5; k++) { 00282 data(FONT_5X7[c][k]); 00283 } 00284 data(0x00); 00285 _lineBuffer[_row][_column] = c; 00286 _column++; 00287 break; 00288 } 00289 return 0; 00290 } 00291 00292 int TextLCD_ST7565SPI::_getc() { 00293 return 0; 00294 } 00295 00296 void TextLCD_ST7565SPI::shiftUp() { 00297 // Move line buffer content 00298 for (uint8_t j = 0; j < _rows - 1; j++) { 00299 memcpy(_lineBuffer[j], _lineBuffer[j + 1], _columns); 00300 } 00301 // Clear last line 00302 memset(_lineBuffer[_rows - 1], ' ', _columns); 00303 00304 // Redraw 00305 for (uint8_t j = 0; j < _rows; j++) { 00306 locate(0, j); 00307 for (uint8_t i = 0; i < _columns; i++) { 00308 for (uint8_t k = 0; k < 5; k++) { 00309 data(FONT_5X7[_lineBuffer[j][i]][k]); 00310 } 00311 data(0x00); 00312 } 00313 } 00314 } 00315 00316 void TextLCD_ST7565SPI::setPage(uint8_t page) { 00317 if (page < 16) { 00318 command(0xb0 | page); 00319 } 00320 } 00321 00322 void TextLCD_ST7565SPI::setColumn(uint8_t column) { 00323 command(0x10 | (column >> 4)); 00324 command(column & 0x0f); 00325 } 00326 00327 void TextLCD_ST7565SPI::command(uint8_t c) { 00328 _rs = 0; 00329 _cs = 0; 00330 _spi.write(c); 00331 _cs = 1; 00332 } 00333 00334 void TextLCD_ST7565SPI::data(uint8_t d) { 00335 _rs = 1; 00336 _cs = 0; 00337 _spi.write(d); 00338 _cs = 1; 00339 }
Generated on Wed Jul 13 2022 18:32:15 by 1.7.2