Text console library for ST7565 graphics LCD controller over SPI interface.

Dependents:   TextLCD_ST7565SPI_Test OpPanel_Offline OpPanel_Offline_cmake_gcc_arm_NUCLEO_F303RENew

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers TextLCD_ST7565SPI.cpp Source File

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 }