Text console library for ST7565 graphics LCD controller over SPI interface.
Dependents: TextLCD_ST7565SPI_Test OpPanel_Offline OpPanel_Offline_cmake_gcc_arm_NUCLEO_F303RENew
Diff: TextLCD_ST7565SPI.cpp
- Revision:
- 0:1ea133b6a4de
- Child:
- 1:a32310f5dab1
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TextLCD_ST7565SPI.cpp Mon Mar 02 23:10:13 2015 +0000 @@ -0,0 +1,334 @@ +// ==================================================== Mar 03 2015, kayeks == +// TextLCD_ST7565SPI.cpp +// =========================================================================== +// Text console library for ST7565 graphics LCD controller over SPI interface. + +#include <string.h> +#include "TextLCD_ST7565SPI.h" + +const uint8_t TextLCD_ST7565SPI::FONT_5X7[128][5] = { + { 0x77, 0x55, 0x55, 0x55, 0x77 }, // unimplemented NUL + { 0x77, 0x52, 0x52, 0x52, 0x76 }, // unimplemented SOH + { 0x77, 0x54, 0x57, 0x51, 0x77 }, // unimplemented STX + { 0x77, 0x51, 0x56, 0x51, 0x77 }, // unimplemented ETX + { 0x71, 0x57, 0x55, 0x55, 0x71 }, // unimplemented EOT + { 0x77, 0x51, 0x57, 0x54, 0x77 }, // unimplemented ENQ + { 0x77, 0x55, 0x57, 0x54, 0x77 }, // unimplemented ACK + { 0x74, 0x54, 0x52, 0x51, 0x77 }, // unimplemented BEL + // 08h..0Fh + { 0x77, 0x55, 0x57, 0x55, 0x77 }, // unimplemented BS + { 0x77, 0x51, 0x57, 0x55, 0x77 }, // unimplemented HT + { 0x75, 0x57, 0x55, 0x55, 0x77 }, // unimplemented LF + { 0x77, 0x55, 0x55, 0x57, 0x74 }, // unimplemented VT + { 0x77, 0x54, 0x54, 0x54, 0x77 }, // unimplemented FF + { 0x77, 0x55, 0x55, 0x57, 0x71 }, // unimplemented CR + { 0x77, 0x54, 0x57, 0x54, 0x77 }, // unimplemented SO + { 0x74, 0x54, 0x57, 0x54, 0x77 }, // unimplemented SI + // 10h..17h + { 0x77, 0x25, 0x25, 0x25, 0x67 }, // unimplemented DLE + { 0x77, 0x22, 0x22, 0x22, 0x66 }, // unimplemented DC1 + { 0x77, 0x24, 0x27, 0x21, 0x67 }, // unimplemented DC2 + { 0x77, 0x21, 0x26, 0x21, 0x67 }, // unimplemented DC3 + { 0x71, 0x27, 0x25, 0x25, 0x61 }, // unimplemented DC4 + { 0x77, 0x21, 0x27, 0x24, 0x67 }, // unimplemented NAK + { 0x77, 0x25, 0x27, 0x24, 0x67 }, // unimplemented SYN + { 0x74, 0x24, 0x22, 0x21, 0x67 }, // unimplemented ETB + // 18h..1Fh + { 0x77, 0x25, 0x27, 0x25, 0x67 }, // unimplemented CAN + { 0x77, 0x21, 0x27, 0x25, 0x67 }, // unimplemented EM + { 0x75, 0x27, 0x25, 0x25, 0x67 }, // unimplemented SUB + { 0x77, 0x25, 0x25, 0x27, 0x64 }, // unimplemented ESC + { 0x77, 0x24, 0x24, 0x24, 0x67 }, // unimplemented FS + { 0x77, 0x25, 0x25, 0x27, 0x61 }, // unimplemented GS + { 0x77, 0x24, 0x27, 0x24, 0x67 }, // unimplemented RS + { 0x74, 0x24, 0x27, 0x24, 0x67 }, // unimplemented US // 20h..27h + // 20h..27h + { 0x00, 0x00, 0x00, 0x00, 0x00 }, // SPC + { 0x00, 0x00, 0x7d, 0x00, 0x00 }, // ! + { 0x00, 0x60, 0x00, 0x60, 0x00 }, // " + { 0x22, 0x7f, 0x22, 0x7f, 0x22 }, // # + { 0x32, 0x49, 0x7f, 0x49, 0x26 }, // $ + { 0x72, 0x54, 0x7f, 0x15, 0x27 }, // % + { 0x36, 0x49, 0x75, 0x02, 0x0d }, // & + { 0x00, 0x20, 0x40, 0x00, 0x00 }, // ' + // 28h..2Fh + { 0x00, 0x00, 0x00, 0x3e, 0x41 }, // ( + { 0x41, 0x3e, 0x00, 0x00, 0x00 }, // ) + { 0x14, 0x08, 0x3e, 0x08, 0x14 }, // * + { 0x08, 0x08, 0x3e, 0x08, 0x08 }, // + + { 0x00, 0x01, 0x02, 0x00, 0x00 }, // , + { 0x08, 0x08, 0x08, 0x08, 0x08 }, // - + { 0x00, 0x00, 0x01, 0x00, 0x00 }, // . + { 0x00, 0x03, 0x1c, 0x60, 0x00 }, // / + // 30h..37h + { 0x3e, 0x41, 0x49, 0x41, 0x3e }, // 0 + { 0x00, 0x41, 0x7f, 0x01, 0x00 }, // 1 + { 0x27, 0x49, 0x49, 0x49, 0x31 }, // 2 + { 0x42, 0x41, 0x51, 0x51, 0x6e }, // 3 + { 0x0e, 0x12, 0x22, 0x7f, 0x02 }, // 4 + { 0x72, 0x51, 0x51, 0x51, 0x4e }, // 5 + { 0x3e, 0x51, 0x51, 0x51, 0x0e }, // 6 + { 0x40, 0x40, 0x47, 0x58, 0x60 }, // 7 + // 38h..3Fh + { 0x36, 0x49, 0x49, 0x49, 0x36 }, // 8 + { 0x38, 0x45, 0x45, 0x45, 0x3e }, // 9 + { 0x00, 0x00, 0x12, 0x00, 0x00 }, // : + { 0x00, 0x01, 0x12, 0x00, 0x00 }, // ; + { 0x00, 0x08, 0x14, 0x22, 0x41 }, // < + { 0x14, 0x14, 0x14, 0x14, 0x14 }, // = + { 0x41, 0x22, 0x14, 0x08, 0x00 }, // > + { 0x20, 0x40, 0x45, 0x48, 0x30 }, // ? + // 40h..47h + { 0x3e, 0x41, 0x5d, 0x55, 0x3c }, // @ + { 0x0f, 0x34, 0x44, 0x34, 0x0f }, // A + { 0x7f, 0x49, 0x49, 0x49, 0x36 }, // B + { 0x3e, 0x41, 0x41, 0x41, 0x22 }, // C + { 0x7f, 0x41, 0x41, 0x41, 0x3e }, // D + { 0x7f, 0x49, 0x49, 0x49, 0x41 }, // E + { 0x7f, 0x48, 0x48, 0x48, 0x40 }, // F + { 0x3e, 0x41, 0x49, 0x49, 0x2e }, // G + // 48h..4Fh + { 0x7f, 0x08, 0x08, 0x08, 0x7f }, // H + { 0x00, 0x41, 0x7f, 0x41, 0x00 }, // I + { 0x02, 0x01, 0x01, 0x41, 0x7e }, // J + { 0x7f, 0x08, 0x14, 0x22, 0x41 }, // K + { 0x7f, 0x01, 0x01, 0x01, 0x01 }, // L + { 0x7f, 0x20, 0x1c, 0x20, 0x7f }, // M + { 0x7f, 0x20, 0x10, 0x08, 0x7f }, // N + { 0x3e, 0x41, 0x41, 0x41, 0x3e }, // O + // 50h..57h + { 0x7f, 0x48, 0x48, 0x48, 0x30 }, // P + { 0x3e, 0x41, 0x45, 0x42, 0x3d }, // Q + { 0x7f, 0x48, 0x4c, 0x4a, 0x31 }, // R + { 0x32, 0x49, 0x49, 0x49, 0x26 }, // S + { 0x40, 0x40, 0x7f, 0x40, 0x40 }, // T + { 0x7e, 0x01, 0x01, 0x01, 0x7e }, // U + { 0x78, 0x06, 0x01, 0x06, 0x78 }, // V + { 0x7e, 0x01, 0x1e, 0x01, 0x7e }, // W + // 58h..5Fh + { 0x63, 0x14, 0x08, 0x14, 0x63 }, // X + { 0x60, 0x10, 0x0f, 0x10, 0x60 }, // Y + { 0x43, 0x45, 0x49, 0x51, 0x61 }, // Z + { 0x00, 0x00, 0x00, 0x7f, 0x41 }, // [ + { 0x00, 0x60, 0x1c, 0x03, 0x00 }, // backslash + { 0x41, 0x7f, 0x00, 0x00, 0x00 }, // ] + { 0x00, 0x20, 0x40, 0x20, 0x00 }, // ^ + { 0x01, 0x01, 0x01, 0x01, 0x01 }, // _ + // 60h..67h + { 0x00, 0x00, 0x40, 0x20, 0x00 }, // ` + { 0x02, 0x15, 0x15, 0x15, 0x0f }, // a + { 0x7f, 0x11, 0x11, 0x11, 0x0e }, // b + { 0x0e, 0x11, 0x11, 0x11, 0x0a }, // c + { 0x0e, 0x11, 0x11, 0x11, 0x7f }, // d + { 0x0e, 0x15, 0x15, 0x15, 0x0c }, // e + { 0x00, 0x08, 0x3f, 0x48, 0x48 }, // f + { 0x08, 0x15, 0x15, 0x15, 0x1e }, // g + // 68h..6Fh + { 0x7f, 0x10, 0x10, 0x10, 0x0f }, // h + { 0x00, 0x10, 0x5f, 0x00, 0x00 }, // i + { 0x01, 0x11, 0x5e, 0x00, 0x00 }, // j + { 0x00, 0x7f, 0x04, 0x0a, 0x11 }, // k + { 0x00, 0x40, 0x7f, 0x00, 0x00 }, // l + { 0x1f, 0x10, 0x1f, 0x10, 0x0f }, // m + { 0x1f, 0x10, 0x10, 0x10, 0x0f }, // n + { 0x0e, 0x11, 0x11, 0x11, 0x0e }, // o + // 70h..77h + { 0x1f, 0x12, 0x12, 0x12, 0x0c }, // p + { 0x0c, 0x12, 0x12, 0x12, 0x1f }, // q + { 0x1f, 0x08, 0x10, 0x10, 0x10 }, // r + { 0x09, 0x15, 0x15, 0x15, 0x12 }, // s + { 0x00, 0x3e, 0x11, 0x11, 0x00 }, // t + { 0x1e, 0x01, 0x01, 0x01, 0x1f }, // u + { 0x18, 0x06, 0x01, 0x06, 0x18 }, // v + { 0x1e, 0x01, 0x0e, 0x01, 0x1e }, // w + // 78h..7Fh + { 0x11, 0x0a, 0x04, 0x0a, 0x11 }, // x + { 0x18, 0x05, 0x05, 0x05, 0x1e }, // y + { 0x11, 0x13, 0x15, 0x19, 0x11 }, // z + { 0x00, 0x00, 0x08, 0x7f, 0x41 }, // { + { 0x00, 0x00, 0x7f, 0x00, 0x00 }, // | + { 0x41, 0x7f, 0x08, 0x00, 0x00 }, // } + { 0x08, 0x10, 0x18, 0x08, 0x10 }, // ~ + { 0x44, 0x44, 0x77, 0x44, 0x77 } // unimplemented DEL +}; + +TextLCD_ST7565SPI::TextLCD_ST7565SPI(PinName mosi, PinName sck, PinName cs, + PinName rs, PinName rst, + uint8_t columns, uint8_t rows) +: + _rs(rs), + _rst(rst), + _spi(mosi, NC, sck), + _cs(cs) +{ + // Allocate line buffer + _columns = columns; + _rows = rows; + _lineBuffer = new uint8_t*[_rows]; + for (uint8_t i = 0; i < _rows; i++) { + _lineBuffer[i] = new uint8_t[_columns]; + } + + // Initialize SPI + _spi.format(8, 0); + + // Initialize pins + _rs = 0; + _rst = 1; + _cs = 1; + + reset(); +} + +TextLCD_ST7565SPI::~TextLCD_ST7565SPI() { + for (uint8_t i = 0; i < _rows; i++) { + delete[] _lineBuffer[i]; + } + delete[] _lineBuffer; +} + +void TextLCD_ST7565SPI::reset() { + wait_ms(10); + _rst = 0; + wait_ms(10); + _rst = 1; +} + +void TextLCD_ST7565SPI::clear() { + for (uint8_t j = 7; j <= 7; j--) { + setPage(j); + setColumn(0); + for (uint8_t i = 0; i < 132; i++) { + data(0x00); + } + } +} + +void TextLCD_ST7565SPI::init(uint8_t v0, uint8_t contrast, Bias bias) { + command(INTERNAL_RESET); + wait_ms(5); + + command(DISPLAY_ON); + command(PCTRL_BOOSTER_ON | PCTRL_REGULATOR_ON | PCTRL_VFOLLOWER_ON); + command(V0_INTERNAL_R_0 + (v0 & 0x07)); + command(ELECTRONIC_VOL_MODE); + if (contrast == 0) { + contrast = 1; + } + command(ELECTRONIC_VOL_1 - 1 + (contrast & 0x3f)); + switch (bias) { + case Bias1_7: + command(BIAS_1_7); + break; + case Bias1_9: + command(BIAS_1_9); + } + command(COMMON_ASCENDING); + command(SEGMENT_ASCENDING); + command(ENTIRE_DISPLAY_OFF); + command(INVERT_DISPLAY_OFF); + command(COMMON_OFFSET); + cls(); +} + +void TextLCD_ST7565SPI::cls() { + clear(); + for (uint8_t j = 0; j < _rows; j++) { + memset(_lineBuffer[j], ' ', _columns); + } + _column = 0; + _row = 0; +} + +void TextLCD_ST7565SPI::locate(uint8_t column, uint8_t row) { + if (column < _columns && row < _rows) { + setPage(_rows - row - 1); + setColumn(6 * column); + _column = column; + _row = row; + } +} + +int TextLCD_ST7565SPI::_putc(int c) { + switch (c) { + case '\r': // Carriage return + _column = 0; + locate(_column, _row); + break; + case '\n': // Line feed + if (_row == _rows - 1) { + shiftUp(); + } else { + _row++; + } + break; + default: + // Break line if the cursor reaches end + if (_column == _columns) { + if (_row == _rows - 1) { + shiftUp(); + } else { + _row++; + } + _column = 0; + } + locate(_column, _row); + for (uint8_t k = 0; k < 5; k++) { + data(FONT_5X7[c][k]); + } + data(0x00); + _lineBuffer[_row][_column] = c; + _column++; + break; + } + return 0; +} + +int TextLCD_ST7565SPI::_getc() { + return 0; +} + +void TextLCD_ST7565SPI::shiftUp() { + // Move line buffer content + for (uint8_t j = 0; j < _rows - 1; j++) { + memcpy(_lineBuffer[j], _lineBuffer[j + 1], _columns); + } + // Clear last line + memset(_lineBuffer[_rows - 1], ' ', _columns); + + // Redraw + for (uint8_t j = 0; j < _rows; j++) { + locate(0, j); + for (uint8_t i = 0; i < _columns; i++) { + for (uint8_t k = 0; k < 5; k++) { + data(FONT_5X7[_lineBuffer[j][i]][k]); + } + data(0x00); + } + } +} + +void TextLCD_ST7565SPI::setPage(uint8_t page) { + if (page < 16) { + command(0xb0 | page); + } +} + +void TextLCD_ST7565SPI::setColumn(uint8_t column) { + command(0x10 | (column >> 4)); + command(column & 0x0f); +} + +void TextLCD_ST7565SPI::command(uint8_t c) { + _rs = 0; + _cs = 0; + _spi.write(c); + _cs = 1; +} + +void TextLCD_ST7565SPI::data(uint8_t d) { + _rs = 1; + _cs = 0; + _spi.write(d); + _cs = 1; +}