A ST7565R display driver written with backbuffering capabilities. Model used and tested: NHD-C12832A1Z-FSW-FBW-3V3
ST7565R.cpp
- Committer:
- celeritous
- Date:
- 2011-08-11
- Revision:
- 0:59cb20947fd6
File content as of revision 0:59cb20947fd6:
#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; } } } }