This is a sample program to drive a 128x128 LCD with t6963 controller through SPI by means of an MCP23S17 16-Bit I/O Expander with Serial Interface

Dependencies:   mbed

main.cpp

Committer:
gertk
Date:
2010-12-06
Revision:
2:9071445a6895
Parent:
1:e98e29ea2d03
Child:
3:fc101c00b5be

File content as of revision 2:9071445a6895:

#include "mbed.h"
#include "mcp_lcd.h"

// for 21 characters on a row (6x8 font)
// #define LCDFONTSEL  0xFF
// for 16 characters on a row (8x8 font)
#define LCDFONTSEL 0xDF

// lcd dimensions in pixels
#define LCD_XWIDTH     128
#define LCD_YHEIGHT    128

#if LCDFONTSEL == 0xFF
// lcd dimensions in characters
#define LCD_WIDTH   22
#define LCD_HEIGHT  16
#else
#define LCD_WIDTH   16
#define LCD_HEIGHT  16
#endif

#define TEXT_STARTADDRESS       0x0000
#define GRAPHIC_STARTADDRESS    0x1000

DigitalOut myled(LED1);
SPI spi(p5, p6, p7); // mosi, miso, sclk
DigitalOut cs(p20);

Serial pc(USBTX, USBRX); // tx, rx


// write 8 bits lcd data
void lcd_data(unsigned char d)
{
    cs=0;
    spi.write(0x40);
    spi.write(GPIOB);  // select GPIOB
    spi.write(d);      // set data byte
    cs=1;

    cs=0;
    spi.write(0x40);
    spi.write(GPIOA);  // select GPIOA
    spi.write(LCDFONTSEL-LCD_CE-LCD_CD);   
    cs=1;

    cs=0;
    spi.write(0x40);
    spi.write(GPIOA);  // select GPIOA
    spi.write(LCDFONTSEL - LCD_WR - LCD_CE - LCD_CD);   
    cs=1;

    cs=0;
    spi.write(0x40);
    spi.write(GPIOA);  // select GPIOA
    spi.write(LCDFONTSEL - LCD_CD);   
    cs=1;
    
}

// write 8 bits lcd command
void lcd_command(unsigned char c)
{
    cs=0;
    spi.write(0x40);
    spi.write(GPIOB);  // select GPIOB
    spi.write(c);      // set data byte
    cs=1;

    cs=0;
    spi.write(0x40);
    spi.write(GPIOA);  // select GPIOA
    spi.write(LCDFONTSEL-LCD_CE);   
    cs=1;

    cs=0;
    spi.write(0x40);
    spi.write(GPIOA);  // select GPIOA
    spi.write(LCDFONTSEL - LCD_WR - LCD_CE);   
    cs=1;

    cs=0;
    spi.write(0x40);
    spi.write(GPIOA);  // select GPIOA
    spi.write(LCDFONTSEL);   
    cs=1;
}

void lcd_init()
{
    cs=0;
    spi.write(0x40);
    spi.write(IODIRA);  // select IODIRA at start
    spi.write(0x00);    // IODIRA all outputs
    spi.write(0x00);    // IODIRB all outputs
    cs=1;
    wait(0.1);
    
    cs=0;
    spi.write(0x40);
    spi.write(GPIOA);  // select GPIOA at start
    spi.write(LCDFONTSEL-LCD_RST);    // activate reset
    spi.write(0x00);    // all B outputs 0
    cs=1;
    wait(0.1);

    cs=0;
    spi.write(0x40);
    spi.write(GPIOA);  // select GPIOA at start
    spi.write(LCDFONTSEL);    // deactivate reset
    cs=1;
    wait(0.1);

    // set text home address at 0x0000
    lcd_data(TEXT_STARTADDRESS%0x100);
    lcd_data(TEXT_STARTADDRESS/0x100);
    lcd_command(TXHOME);
    
    // set graphic home address at 0x1000
    lcd_data(GRAPHIC_STARTADDRESS%0x100);
    lcd_data(GRAPHIC_STARTADDRESS/0x100);
    lcd_command(GRHOME);
    
    // set text area 
    lcd_data(LCD_WIDTH);
    lcd_data(0x00);
    lcd_command(TXAREA);

    // set graphic area
    lcd_data(LCD_WIDTH);
    lcd_data(0x00);
    lcd_command(GRAREA);
    
    // mode set (internal character generation mode)
    lcd_command(0x80);
    
    // set offset register
    lcd_data(0x02);
    lcd_data(0x00);
    lcd_command(OFFSET);
    
    // display mode (text on graphics on cursor off)
    lcd_command(0x90+0x08+0x04);
        
}

// put a text string at position x,y (character row,column)
void lcd_string(char x,char y,char *s)
{
    int adr;
    adr=TEXT_STARTADDRESS+x+y*LCD_WIDTH;
    lcd_data(adr%0x100);
    lcd_data(adr/0x100);
    lcd_command(ADPSET);
    lcd_command(AWRON);
    
    while (s[0])
    {
        // convert from ascii to t6963
        lcd_data(s[0]-32);
        s++;
    }
    lcd_command(AWROFF);
}

// clear lcd display memory (8k)        
void lcd_cls()
{
    int a;
    lcd_data(0x00);
    lcd_data(0x00);
    lcd_command(ADPSET);
    lcd_command(AWRON);
    for (a=0; a<8192; a++) lcd_data(0);
    lcd_command(AWROFF);
}

// set or reset a pixel on the display on position x,y with color 0 or 1
void lcd_plot(char x,char y,char color)
{
    int adr;                         
    adr = GRAPHIC_STARTADDRESS + ((LCD_WIDTH) * y) + (x/8);   // calculate offset
    lcd_data(adr%0x100);       // set low byte
    lcd_data(adr/0x100);       // set high byte
    lcd_command(ADPSET);           // set address pointer
    if (color) lcd_command(BS + (7-(x%8)));   // use bit set mode
        else  lcd_command(BR + (7-(x%8)));  // use bit reset mode
}

int main() {

    int a;
    pc.printf("SPI test\n");
    
    // set SPI to full speed (10 MHz mode)
    spi.format(8,0);
    spi.frequency(10000000);
//    spi.frequency(10000);
    wait(0.1);

    pc.printf("MCP init\n");
    lcd_init();
    lcd_cls();

    // write some text    
    lcd_string(0,0,"Hello World!");
    lcd_string(0,2,"0123456789");
    lcd_string(0,15,"abcdefghijklmnopqrstuvwxyz");
   
    for (a=0; a<128; a++) lcd_plot(a,a/2+48,1);
    
    while(1) {
        myled = 1;
        wait(0.2);
        myled = 0;
        wait(0.2);
    }
}