A ST7565R display driver written with backbuffering capabilities. Model used and tested: NHD-C12832A1Z-FSW-FBW-3V3

Dependents:   xivelyboard

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;
            }
        }
    }

}