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

Committer:
gertk
Date:
Mon Dec 06 20:45:00 2010 +0000
Revision:
2:9071445a6895
Parent:
1:e98e29ea2d03
Child:
3:fc101c00b5be
0.0003

Who changed what in which revision?

UserRevisionLine numberNew contents of line
gertk 0:bf72877f77ab 1 #include "mbed.h"
gertk 1:e98e29ea2d03 2 #include "mcp_lcd.h"
gertk 0:bf72877f77ab 3
gertk 2:9071445a6895 4 // for 21 characters on a row (6x8 font)
gertk 2:9071445a6895 5 // #define LCDFONTSEL 0xFF
gertk 2:9071445a6895 6 // for 16 characters on a row (8x8 font)
gertk 2:9071445a6895 7 #define LCDFONTSEL 0xDF
gertk 2:9071445a6895 8
gertk 2:9071445a6895 9 // lcd dimensions in pixels
gertk 2:9071445a6895 10 #define LCD_XWIDTH 128
gertk 2:9071445a6895 11 #define LCD_YHEIGHT 128
gertk 2:9071445a6895 12
gertk 2:9071445a6895 13 #if LCDFONTSEL == 0xFF
gertk 2:9071445a6895 14 // lcd dimensions in characters
gertk 2:9071445a6895 15 #define LCD_WIDTH 22
gertk 2:9071445a6895 16 #define LCD_HEIGHT 16
gertk 2:9071445a6895 17 #else
gertk 2:9071445a6895 18 #define LCD_WIDTH 16
gertk 2:9071445a6895 19 #define LCD_HEIGHT 16
gertk 2:9071445a6895 20 #endif
gertk 2:9071445a6895 21
gertk 2:9071445a6895 22 #define TEXT_STARTADDRESS 0x0000
gertk 2:9071445a6895 23 #define GRAPHIC_STARTADDRESS 0x1000
gertk 2:9071445a6895 24
gertk 0:bf72877f77ab 25 DigitalOut myled(LED1);
gertk 0:bf72877f77ab 26 SPI spi(p5, p6, p7); // mosi, miso, sclk
gertk 0:bf72877f77ab 27 DigitalOut cs(p20);
gertk 0:bf72877f77ab 28
gertk 0:bf72877f77ab 29 Serial pc(USBTX, USBRX); // tx, rx
gertk 0:bf72877f77ab 30
gertk 0:bf72877f77ab 31
gertk 0:bf72877f77ab 32 // write 8 bits lcd data
gertk 0:bf72877f77ab 33 void lcd_data(unsigned char d)
gertk 0:bf72877f77ab 34 {
gertk 0:bf72877f77ab 35 cs=0;
gertk 0:bf72877f77ab 36 spi.write(0x40);
gertk 0:bf72877f77ab 37 spi.write(GPIOB); // select GPIOB
gertk 0:bf72877f77ab 38 spi.write(d); // set data byte
gertk 0:bf72877f77ab 39 cs=1;
gertk 0:bf72877f77ab 40
gertk 0:bf72877f77ab 41 cs=0;
gertk 0:bf72877f77ab 42 spi.write(0x40);
gertk 0:bf72877f77ab 43 spi.write(GPIOA); // select GPIOA
gertk 0:bf72877f77ab 44 spi.write(LCDFONTSEL-LCD_CE-LCD_CD);
gertk 0:bf72877f77ab 45 cs=1;
gertk 0:bf72877f77ab 46
gertk 0:bf72877f77ab 47 cs=0;
gertk 0:bf72877f77ab 48 spi.write(0x40);
gertk 0:bf72877f77ab 49 spi.write(GPIOA); // select GPIOA
gertk 0:bf72877f77ab 50 spi.write(LCDFONTSEL - LCD_WR - LCD_CE - LCD_CD);
gertk 0:bf72877f77ab 51 cs=1;
gertk 0:bf72877f77ab 52
gertk 0:bf72877f77ab 53 cs=0;
gertk 0:bf72877f77ab 54 spi.write(0x40);
gertk 0:bf72877f77ab 55 spi.write(GPIOA); // select GPIOA
gertk 0:bf72877f77ab 56 spi.write(LCDFONTSEL - LCD_CD);
gertk 0:bf72877f77ab 57 cs=1;
gertk 0:bf72877f77ab 58
gertk 0:bf72877f77ab 59 }
gertk 0:bf72877f77ab 60
gertk 0:bf72877f77ab 61 // write 8 bits lcd command
gertk 0:bf72877f77ab 62 void lcd_command(unsigned char c)
gertk 0:bf72877f77ab 63 {
gertk 0:bf72877f77ab 64 cs=0;
gertk 0:bf72877f77ab 65 spi.write(0x40);
gertk 0:bf72877f77ab 66 spi.write(GPIOB); // select GPIOB
gertk 0:bf72877f77ab 67 spi.write(c); // set data byte
gertk 0:bf72877f77ab 68 cs=1;
gertk 0:bf72877f77ab 69
gertk 0:bf72877f77ab 70 cs=0;
gertk 0:bf72877f77ab 71 spi.write(0x40);
gertk 0:bf72877f77ab 72 spi.write(GPIOA); // select GPIOA
gertk 0:bf72877f77ab 73 spi.write(LCDFONTSEL-LCD_CE);
gertk 0:bf72877f77ab 74 cs=1;
gertk 0:bf72877f77ab 75
gertk 0:bf72877f77ab 76 cs=0;
gertk 0:bf72877f77ab 77 spi.write(0x40);
gertk 0:bf72877f77ab 78 spi.write(GPIOA); // select GPIOA
gertk 0:bf72877f77ab 79 spi.write(LCDFONTSEL - LCD_WR - LCD_CE);
gertk 0:bf72877f77ab 80 cs=1;
gertk 0:bf72877f77ab 81
gertk 0:bf72877f77ab 82 cs=0;
gertk 0:bf72877f77ab 83 spi.write(0x40);
gertk 0:bf72877f77ab 84 spi.write(GPIOA); // select GPIOA
gertk 0:bf72877f77ab 85 spi.write(LCDFONTSEL);
gertk 0:bf72877f77ab 86 cs=1;
gertk 0:bf72877f77ab 87 }
gertk 0:bf72877f77ab 88
gertk 0:bf72877f77ab 89 void lcd_init()
gertk 0:bf72877f77ab 90 {
gertk 0:bf72877f77ab 91 cs=0;
gertk 0:bf72877f77ab 92 spi.write(0x40);
gertk 0:bf72877f77ab 93 spi.write(IODIRA); // select IODIRA at start
gertk 0:bf72877f77ab 94 spi.write(0x00); // IODIRA all outputs
gertk 0:bf72877f77ab 95 spi.write(0x00); // IODIRB all outputs
gertk 0:bf72877f77ab 96 cs=1;
gertk 0:bf72877f77ab 97 wait(0.1);
gertk 0:bf72877f77ab 98
gertk 0:bf72877f77ab 99 cs=0;
gertk 0:bf72877f77ab 100 spi.write(0x40);
gertk 0:bf72877f77ab 101 spi.write(GPIOA); // select GPIOA at start
gertk 0:bf72877f77ab 102 spi.write(LCDFONTSEL-LCD_RST); // activate reset
gertk 0:bf72877f77ab 103 spi.write(0x00); // all B outputs 0
gertk 0:bf72877f77ab 104 cs=1;
gertk 0:bf72877f77ab 105 wait(0.1);
gertk 0:bf72877f77ab 106
gertk 0:bf72877f77ab 107 cs=0;
gertk 0:bf72877f77ab 108 spi.write(0x40);
gertk 0:bf72877f77ab 109 spi.write(GPIOA); // select GPIOA at start
gertk 0:bf72877f77ab 110 spi.write(LCDFONTSEL); // deactivate reset
gertk 0:bf72877f77ab 111 cs=1;
gertk 0:bf72877f77ab 112 wait(0.1);
gertk 0:bf72877f77ab 113
gertk 0:bf72877f77ab 114 // set text home address at 0x0000
gertk 2:9071445a6895 115 lcd_data(TEXT_STARTADDRESS%0x100);
gertk 2:9071445a6895 116 lcd_data(TEXT_STARTADDRESS/0x100);
gertk 0:bf72877f77ab 117 lcd_command(TXHOME);
gertk 0:bf72877f77ab 118
gertk 2:9071445a6895 119 // set graphic home address at 0x1000
gertk 2:9071445a6895 120 lcd_data(GRAPHIC_STARTADDRESS%0x100);
gertk 2:9071445a6895 121 lcd_data(GRAPHIC_STARTADDRESS/0x100);
gertk 0:bf72877f77ab 122 lcd_command(GRHOME);
gertk 0:bf72877f77ab 123
gertk 2:9071445a6895 124 // set text area
gertk 2:9071445a6895 125 lcd_data(LCD_WIDTH);
gertk 0:bf72877f77ab 126 lcd_data(0x00);
gertk 0:bf72877f77ab 127 lcd_command(TXAREA);
gertk 0:bf72877f77ab 128
gertk 2:9071445a6895 129 // set graphic area
gertk 2:9071445a6895 130 lcd_data(LCD_WIDTH);
gertk 0:bf72877f77ab 131 lcd_data(0x00);
gertk 0:bf72877f77ab 132 lcd_command(GRAREA);
gertk 0:bf72877f77ab 133
gertk 0:bf72877f77ab 134 // mode set (internal character generation mode)
gertk 0:bf72877f77ab 135 lcd_command(0x80);
gertk 0:bf72877f77ab 136
gertk 0:bf72877f77ab 137 // set offset register
gertk 0:bf72877f77ab 138 lcd_data(0x02);
gertk 0:bf72877f77ab 139 lcd_data(0x00);
gertk 0:bf72877f77ab 140 lcd_command(OFFSET);
gertk 0:bf72877f77ab 141
gertk 0:bf72877f77ab 142 // display mode (text on graphics on cursor off)
gertk 2:9071445a6895 143 lcd_command(0x90+0x08+0x04);
gertk 2:9071445a6895 144
gertk 2:9071445a6895 145 }
gertk 2:9071445a6895 146
gertk 2:9071445a6895 147 // put a text string at position x,y (character row,column)
gertk 2:9071445a6895 148 void lcd_string(char x,char y,char *s)
gertk 2:9071445a6895 149 {
gertk 2:9071445a6895 150 int adr;
gertk 2:9071445a6895 151 adr=TEXT_STARTADDRESS+x+y*LCD_WIDTH;
gertk 2:9071445a6895 152 lcd_data(adr%0x100);
gertk 2:9071445a6895 153 lcd_data(adr/0x100);
gertk 2:9071445a6895 154 lcd_command(ADPSET);
gertk 2:9071445a6895 155 lcd_command(AWRON);
gertk 0:bf72877f77ab 156
gertk 2:9071445a6895 157 while (s[0])
gertk 2:9071445a6895 158 {
gertk 2:9071445a6895 159 // convert from ascii to t6963
gertk 2:9071445a6895 160 lcd_data(s[0]-32);
gertk 2:9071445a6895 161 s++;
gertk 2:9071445a6895 162 }
gertk 2:9071445a6895 163 lcd_command(AWROFF);
gertk 2:9071445a6895 164 }
gertk 2:9071445a6895 165
gertk 2:9071445a6895 166 // clear lcd display memory (8k)
gertk 2:9071445a6895 167 void lcd_cls()
gertk 2:9071445a6895 168 {
gertk 2:9071445a6895 169 int a;
gertk 0:bf72877f77ab 170 lcd_data(0x00);
gertk 0:bf72877f77ab 171 lcd_data(0x00);
gertk 0:bf72877f77ab 172 lcd_command(ADPSET);
gertk 0:bf72877f77ab 173 lcd_command(AWRON);
gertk 2:9071445a6895 174 for (a=0; a<8192; a++) lcd_data(0);
gertk 0:bf72877f77ab 175 lcd_command(AWROFF);
gertk 2:9071445a6895 176 }
gertk 2:9071445a6895 177
gertk 2:9071445a6895 178 // set or reset a pixel on the display on position x,y with color 0 or 1
gertk 2:9071445a6895 179 void lcd_plot(char x,char y,char color)
gertk 2:9071445a6895 180 {
gertk 2:9071445a6895 181 int adr;
gertk 2:9071445a6895 182 adr = GRAPHIC_STARTADDRESS + ((LCD_WIDTH) * y) + (x/8); // calculate offset
gertk 2:9071445a6895 183 lcd_data(adr%0x100); // set low byte
gertk 2:9071445a6895 184 lcd_data(adr/0x100); // set high byte
gertk 2:9071445a6895 185 lcd_command(ADPSET); // set address pointer
gertk 2:9071445a6895 186 if (color) lcd_command(BS + (7-(x%8))); // use bit set mode
gertk 2:9071445a6895 187 else lcd_command(BR + (7-(x%8))); // use bit reset mode
gertk 2:9071445a6895 188 }
gertk 2:9071445a6895 189
gertk 2:9071445a6895 190 int main() {
gertk 2:9071445a6895 191
gertk 2:9071445a6895 192 int a;
gertk 2:9071445a6895 193 pc.printf("SPI test\n");
gertk 2:9071445a6895 194
gertk 2:9071445a6895 195 // set SPI to full speed (10 MHz mode)
gertk 2:9071445a6895 196 spi.format(8,0);
gertk 2:9071445a6895 197 spi.frequency(10000000);
gertk 2:9071445a6895 198 // spi.frequency(10000);
gertk 2:9071445a6895 199 wait(0.1);
gertk 2:9071445a6895 200
gertk 2:9071445a6895 201 pc.printf("MCP init\n");
gertk 2:9071445a6895 202 lcd_init();
gertk 2:9071445a6895 203 lcd_cls();
gertk 0:bf72877f77ab 204
gertk 0:bf72877f77ab 205 // write some text
gertk 2:9071445a6895 206 lcd_string(0,0,"Hello World!");
gertk 2:9071445a6895 207 lcd_string(0,2,"0123456789");
gertk 2:9071445a6895 208 lcd_string(0,15,"abcdefghijklmnopqrstuvwxyz");
gertk 2:9071445a6895 209
gertk 2:9071445a6895 210 for (a=0; a<128; a++) lcd_plot(a,a/2+48,1);
gertk 2:9071445a6895 211
gertk 0:bf72877f77ab 212 while(1) {
gertk 0:bf72877f77ab 213 myled = 1;
gertk 0:bf72877f77ab 214 wait(0.2);
gertk 0:bf72877f77ab 215 myled = 0;
gertk 0:bf72877f77ab 216 wait(0.2);
gertk 0:bf72877f77ab 217 }
gertk 0:bf72877f77ab 218 }