Simple driver for the ST7920 graphic LCD 128x64. Basic functions for displaying internal ROM fonts like a 16x4 LCD Extended function to fill the screen with a bitmap

st7920.cpp

Committer:
Bas
Date:
2012-06-29
Revision:
0:1a97e0243dbc

File content as of revision 0:1a97e0243dbc:

#include "st7920.h"

ST7920::ST7920 (PinName _RS,PinName _RW, PinName _E, PinName DB0, PinName DB1, PinName DB2, PinName DB3, PinName DB4, PinName DB5, PinName DB6, PinName DB7)
        : DB(DB0,DB1,DB2,DB3,DB4,DB5,DB6,DB7),RS(_RS), RW(_RW), E(_E) {

    DB.output();
    E.write(0);
    RS.write(0);
    RW.write(0);
    InitDisplay();
}

unsigned int ST7920::ByteReadLCD() {
    unsigned int data;

    DB.input();
    E.write(1);
    data = DB.read();
    E.write(0);
    DB.output();

    return data;
}

void ST7920::ByteWriteLCD(unsigned int data) {
    DB.output();
    E.write(1);
    DB.write(data);
    E.write(0);
}

void ST7920::WriteInstruction(unsigned int Command) {
    ReadBusyFlag();
    RS.write(0);
    RW.write(0);
    ByteWriteLCD(Command);
}

void ST7920::WriteRAM(unsigned int data) {
    ReadBusyFlag();
    RS.write(1);
    RW.write(0);
    ByteWriteLCD(data);
}

void ST7920::ReadBusyFlag() {
    unsigned char data;

    RS.write(0);
    RW.write(1);
    while ((data & 0x7F) == BUSY_FLAG_BF) {
        data = ByteReadLCD();
    }
}

unsigned int ST7920::Read_AC() {
    RS.write(0);
    RW.write(1);
    return (ByteReadLCD() & 0x7F);
}

unsigned int ST7920::ReadRAM() {
    ReadBusyFlag();
    RS.write(1);
    RW.write(1);
    return ByteReadLCD();
}

void ST7920::InitDisplay() {
    wait_ms(40); // wait 40ms
    E.write(0);
    WriteInstruction(FUNCTION_SET | DATA_LENGTH_DL); // 8 bits interface, RE=0
    wait_us(100); // wait 100us
    WriteInstruction(FUNCTION_SET | DATA_LENGTH_DL); // again
    wait_us(37); // wait 37us
    WriteInstruction(DISPLAY_CONTROL | DISPLAY_ON_D ); // display on
    wait_us(100); // wait 100us
    WriteInstruction(DISPLAY_CLEAR); // clear display
    wait_ms(10); // wait 10ms
    WriteInstruction(ENTRY_MODE_SET | INCREASE_DECREASE_ID); // move cursor right
    wait_ms(10); // wait 10ms
    WriteInstruction(RETURN_HOME);
    SetGraphicsMode();
}

//************************************************************************************************
//public methodes
void ST7920::SetGraphicsMode() {
    WriteInstruction(EXTENDED_FUNCTION_SET | DATA_LENGTH_DL);
    WriteInstruction(EXTENDED_FUNCTION_SET | DATA_LENGTH_DL | EXTENDED_INSTRUCTION_RE); //RE=1 (Extended funtion set)
    WriteInstruction(EXTENDED_FUNCTION_SET | DATA_LENGTH_DL | EXTENDED_INSTRUCTION_RE | GRAPHIC_ON_G);
}

void ST7920::SetTextMode() {
    WriteInstruction(FUNCTION_SET | DATA_LENGTH_DL); // RE=0 (Basic funtion set)
}

void ST7920::ClearScreen() {
    WriteInstruction(FUNCTION_SET | DATA_LENGTH_DL); // RE=0 (Basic funtion set)
    WriteInstruction(DISPLAY_CLEAR);
}

void ST7920::ReturnHome() {
    WriteInstruction(FUNCTION_SET | DATA_LENGTH_DL); //RE=0 (Basic funtion set)
    WriteInstruction(RETURN_HOME);
}

void ST7920::Standby() {
    WriteInstruction(EXTENDED_FUNCTION_SET | DATA_LENGTH_DL | EXTENDED_INSTRUCTION_RE); //RE=1 (Extended funtion set)
    WriteInstruction(STANDBY);
}

//Basic text functions
void ST7920::DisplayString(int Row,int Column,unsigned char *ptr,int length) {
    int i=0;

    switch (Row) {
        case 0:
            Column|=0x80;
            break;
        case 1:
            Column|=0x90;
            break;
        case 2:
            Column|=0x88;
            break;
        case 3:
            Column|=0x98;
            break;
        default:
            Column=0x80;
            break;
    }

    if (Column%2!=0) {
        Column-=1;
        i=1;
    }
    WriteInstruction((unsigned int)Column);

    if (i==1) {
        WriteRAM(' ');
    }
    for (i=0; i<length; i++) {
        WriteRAM((unsigned int)ptr[i]);
    }
}

void ST7920::DisplayChar(int Row,int Column,int inpChr) {
    int i=0;

    switch (Row) {
        case 0:
            Column|=0x80; // SET_DDRAM_ADDRESS
            break;
        case 1:
            Column|=0x90;
            break;
        case 2:
            Column|=0x88;
            break;
        case 3:
            Column|=0x98;
            break;
        default:
            Column=0x80;
            break;
    }

    if (Column%2!=0) {
        Column-=1;
        i=1;
    }
    WriteInstruction((unsigned int)Column);

    if (i==1) {
        WriteRAM(' ');
    }
    WriteRAM((unsigned int)inpChr);
}

// Graphic functions
void ST7920::FillGDRAM(unsigned char *bitmap) {
    unsigned char i, j, k ;

    for ( i = 0 ; i < 2 ; i++ ) {
        for ( j = 0 ; j < 32 ; j++ ) {
            WriteInstruction(SET_GRAPHIC_RAM_ADDRESS | j) ;
            if ( i == 0 ) {
                WriteInstruction(SET_GRAPHIC_RAM_ADDRESS) ;
            } else {
                WriteInstruction(SET_GRAPHIC_RAM_ADDRESS | 0x08) ;
            }
            for ( k = 0 ; k < 16 ; k++ ) {
                WriteRAM( *bitmap++ ) ;
            }
        }
    }
}

void ST7920::FillGDRAM_Turned(unsigned char *bitmap) {
    int i, j, k, m, offset_row, mask ;
    unsigned char data;

    for ( i = 0 ; i < 2 ; i++ ) { //upper and lower page
        for ( j = 0 ; j < 32 ; j++ ) { //32 lines per page
            WriteInstruction(SET_GRAPHIC_RAM_ADDRESS | j) ;
            if ( i == 0 ) {
                WriteInstruction(SET_GRAPHIC_RAM_ADDRESS) ;
            } else {
                WriteInstruction(SET_GRAPHIC_RAM_ADDRESS | 0x08) ;
            }
            mask=1<<(j%8); // extract bitnumber
            //printf("mask: %d\r\n",mask);
            for ( k = 0 ; k < 16 ; k++ ) { //16 bytes per line
                offset_row=((i*32+j)/8)*128 + k*8; //y coordinate/8 = row 0-7 * 128 = byte offset, read 8 bytes
                data=0;
                for (m = 0 ; m < 8 ; m++) { // read 8 bytes from source

                    if ((bitmap[offset_row+m] & mask)) { //pixel = 1
                        data|=(128>>m);
                    }
                }
                WriteRAM(data) ;
            }
        }
    }
}

void ST7920::ClearGDRAM() {
    unsigned char i, j, k ;

    for ( i = 0 ; i < 2 ; i++ ) {
        for ( j = 0 ; j < 32 ; j++ ) {
            WriteInstruction(SET_GRAPHIC_RAM_ADDRESS | j) ;
            if ( i == 0 ) {
                WriteInstruction(SET_GRAPHIC_RAM_ADDRESS) ;
            } else {
                WriteInstruction(SET_GRAPHIC_RAM_ADDRESS | 0x08) ;
            }
            for ( k = 0 ; k < 16 ; k++ ) {
                WriteRAM(0);
            }
        }
    }
}