A ST7565R display driver written with backbuffering capabilities. Model used and tested: NHD-C12832A1Z-FSW-FBW-3V3
Diff: ST7565R.cpp
- Revision:
- 0:59cb20947fd6
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ST7565R.cpp Thu Aug 11 16:00:05 2011 +0000 @@ -0,0 +1,202 @@ + +#include "ST7565R.h" +#include "mbed.h" + +ST7565R::ST7565R(PinName cs, PinName a0, PinName scl, PinName si, PinName rst, bool BackBuffer) : _cs(cs), _a0(a0), _spi(si, NC, scl), _rst(rst) +{ + _spi.format(8,3); + _spi.frequency(20000000); //datasheet 50 ns sclk + _rst=1; + _a0=0; + _cs=1; + scr=1; + reset(); + UsingBackBuffer = BackBuffer; +} + +void ST7565R::reset() +{ + _rst = 0; + wait_ms(1); + _rst = 1; + wait_ms(1); + command(0xA0); + command(0xAF); + command(0xC0); + command(0xA2); + command(0x2F); + command(0x24); + command(0x81); + command(0x00); + command(0xA7); + + + clearBuffer(); + +} +#define FONT_SIZE_X 6 +#define FONT_SIZE_Y 8 +void ST7565R::moveto(int col, int row) +{ + _column = col; + _row = row; +} +void ST7565R::character(int column, int row, char c) +{ + char v = c - 0x20; + if (c >= 0x20 && c < 0x80) + { + c-=0x20; + bitblt(column*FONT_SIZE_X,row*FONT_SIZE_Y, + FONT_SIZE_X, FONT_SIZE_Y, (char*)TEXT, + TEXT_WIDTH, TEXT_HEIGHT, + (v%0x10) * FONT_SIZE_X, (v/0x10)*FONT_SIZE_Y,BITBLT_SRCCOPY); + } +} +int ST7565R::_putc(int value) { + if (value == '\n') { + _column = 0; + _row++; + if (_row >= rows()) { + _row = 0; + } + } else { + character(_column, _row, value); + _column++; + if (_column >= columns()) { + _column = 0; + _row++; + if (_row >= rows()) { + _row = 0; + } + } + } + return value; +} + +int ST7565R::rows() { return 4; } +int ST7565R::columns() { return 21; } +int ST7565R::_getc() { + return -1; +} + + +void ST7565R::clearBuffer() +{ + + char * screen =getDrawingScreen(); + int i=512; + while(i--) + screen[i]=0xff; + + + if (!UsingBackBuffer) + swapBuffers(); //should just commit the white to memory +} +void ST7565R::setpixel(int x, int y) +{ + if (x < 0 || x > 127) return; + if (y < 0 || y > 31) return; + char * screen = getDrawingScreen(); + loc_t byte = { x , (y / 8) * 128}; + screen[byte.y + byte.x] |= 0x80 >> (y%8); + + //if theres no backbuffer,then we'll do our writes immediately + if (!UsingBackBuffer) + { + command(0xb0 | ( (3-(y/8))+scr*4)); + command(0x10 | (x >> 4)); //column upper + command(0x00 | (x & 0x0f)); //column lower + data(screen[byte.y +byte.x]); + } +} + +void ST7565R::clearpixel(int x, int y) +{ + if (x < 0 || x > 127) return; + if (y < 0 || y > 31) return; + char * screen = getDrawingScreen(); + loc_t byte = { x , (y / 8) * 128}; + screen[byte.y + byte.x] &= ~(0x80 >> (y%8)); + + //if theres no backbuffer,then we'll do our writes immediately + if (!UsingBackBuffer) + { + command(0xb0 | ( (3-(y/8))+scr*4)); + command(0x10 | (x >> 4)); //column upper + command(0x00 | (x & 0x0f)); //column lower + data(screen[byte.y +byte.x]); + } +} + +void ST7565R::data(int value) +{ + _cs = 0; + _a0 = 1; + _spi.write(value); + _cs = 1; + +} +void ST7565R::command(int value) +{ + _cs = 0; + _a0 = 0; + _spi.write(value); + _cs = 1; +} + +void ST7565R::swapBuffers() +{ + char * screen = getDrawingScreen(); + for (int i=0; i<4; i++) + { + + command(0xb0 | ( (3-i)+scr*4)); + command(0x10); + command(0x00); + for (int j=0; j<128; j++) + { + data(screen[i*128+j]); + } + } + command(0x40 | scr * 32); + if (UsingBackBuffer) scr^=1; +} +#define SCREEN_1 0 +#define SCREEN_2 1 + + +char * ST7565R::getDrawingScreen() +{ + if (scr) + return screen.screen1; + else + return screen.screen2; +} +void ST7565R::bitblt(int dstx, int dsty, + int blit_width, int blit_height, + char* img, + int img_width, int img_height, + int srcx, int srcy, + int format) +{ + char * current_draw_buffer = getDrawingScreen(); + bool pixel = 0; + int byte_size_wide = img_width / 8; + for (int i=0; i < blit_height; i++) + { + for (int j=0; j < blit_width; j++) + { + pixel = img[ byte_size_wide*(srcy+i) + (srcx+j)/8] & (0x80 >> ((srcx+j)%8)); + + switch(format) + { + case BITBLT_SRCCOPY: if (pixel) setpixel(dstx+j,dsty+i); else + clearpixel(dstx+j,dsty+i); break; + case BITBLT_SRCOR: if (pixel) setpixel(dstx+j,dsty+i); break; + case BITBLT_SRCAND: if (!pixel) clearpixel(dstx+j,dsty+i); break; + } + } + } + +}