Very simple library for controlling small graphic LCDs

Dependents:   LCD

lcd.cpp

Committer:
HBP
Date:
2011-03-03
Revision:
0:573607103077

File content as of revision 0:573607103077:

#include "lcd.h"

BusOut LcdDB(p21, p22, p23, p24, p25, p26, p27, p28);
DigitalOut LcdRS(p18);
DigitalOut LcdRW(p19);
DigitalOut LcdEN(p20);

#define bit_set(p,m) ((p) |= (1<<m))
#define bit_clear(p,m) ((p) &= ~(1<<m)) 

/* Delays needed to use the LCD */
#define COMMAND_DELAY 15  // ns
#define SHORT_DELAY   10  // us
#define LONG_DELAY    100 // ms
#define STARTDELAY    50  // ms

gfxLcd::gfxLcd()
{
    init();
}

void gfxLcd::init()
{
    // Set all to low
    LcdDB = 0x00;
    LcdRS = 0x00;
    LcdRW = 0x00;
    LcdEN = 0x00;
    
    wait_ms(STARTDELAY);
    
    // TODO: Try if the amount of commands could be reduced
    //       and delays shortened
    
    // Specify 8 bit interface and basic instruction set
    write(0, 0x30);
    wait_us(LONG_DELAY); 
    // Specify 8 bit interface and basic instruction set
    write(0, 0x30);
    wait_us(SHORT_DELAY);
    // Specify Display on, Cursor off and Blink off
    write(0, 0x0C);
    wait_us(SHORT_DELAY);
    // Display clear.
    write(0, 0x01); 
    wait_ms(SHORT_DELAY);
    // AC Increase (cursor move right), don't shift the display
    write(0, 0x06); 
    wait_us(SHORT_DELAY);
    // Select extended instruction set
    write(0, 0x34);
    wait_us(SHORT_DELAY);
    // Graphic display ON
    write(0, 0x36);

    fillScreen(false);
    update(); // Refresh display
}

void gfxLcd::write(bool rs, char c)
{ 
    // Writes an instruction/data to the LCD   
    LcdRS = rs;
    wait_us(SHORT_DELAY); 
    LcdRW = 0;
    wait_us(SHORT_DELAY);
    LcdEN = 0;
    LcdDB = c;
    wait_us(SHORT_DELAY);
    LcdEN = 1;
    wait_us(COMMAND_DELAY); 
    LcdEN = 0; 
} 

void gfxLcd::fillScreen(bool color)
{ 
  char v, h; 
  uint32_t d; 

  d = (color == true ? 0xFFFFL : 0x0000L); 

  for (v=0; v<32; v++) 
  { 
    for (h=0; h<160; h++) 
    { 
      fbuf.dots[v][h].word = d; 
    } 
  } 
  fbuf.refresh = true; 
}

void gfxLcd::putPixel(char x, char y, bool color)
{ 
    uint32_t v, h, b;

    v = y;
    h = x/16;
    b = 15 - (x%16); 

    // Modify the actual word
    if (color == true)
        bit_set(fbuf.dots[v][h].word, b);
    else
        bit_clear(fbuf.dots[v][h].word, b); 
  
    fbuf.refresh = true; 
} 

void gfxLcd::update()
{
    char v, h; 
    
    if (fbuf.refresh == true) 
    { 
        for (v=0; v<32; v++) 
        { 
            write(0, 0x80 | v); // Set Vertical Address
            write(0, 0x80 | 0); // Set Horizontal Address

            for (h=0; h<10; h++) 
            {
                write(1, fbuf.dots[v][h].byte[1]); // Write High Byte
                write(1, fbuf.dots[v][h].byte[0]); // Write Low Byte
            }
        }
        fbuf.refresh = false; 
    }
}