/* simple low-level device driver for a KS0108 controlled LCD * * 29.03.06 - new version for TinyMips * 13.10.00 - first version, copied from Claas' graphics.c */ #include "ks0108.h" // fixed address for the LCDAdapter subdesign // //#define BASEADDR 0x00080000 #define BASEADDR 0xa0080000 // bits 0..7 connected to display D0..D7, bit 8 connected to RS, etc. // #define DATA_MASK 0x00ff #define RS_MASK 0x0100 #define RW_MASK 0x0200 #define CHIP1_MASK 0x0400 #define CHIP2_MASK 0x0800 #define NR_MASK 0x1000 #define ENAMASK 0x2000 // because the chip-selects are active low, these appear inverted... #define CHIP1 0x0800 #define CHIP2 0x0400 #define DISPLAYON 0x103e #define SETPAGEADR 0x10b0 #define SETBYTEADR 0x1040 #define SETSTARTADR 0x10c0 #define WRITE 0x1100 int internalColor = 1; int xpos = 0; int ypos = 0; int chipselect = CHIP1; unsigned char charset[128][7] = { { 0,0,0,0,0,0,0 }, // 0 { 0,0,0,0,0,0,0 }, // 1 { 0,0,0,0,0,0,0 }, // 2 { 0,0,0,0,0,0,0 }, // 3 { 0,0,0,0,0,0,0 }, // 4 { 0,0,0,0,0,0,0 }, // 5 { 0,0,0,0,0,0,0 }, // 6 { 0,0,0,0,0,0,0 }, // 7 { 0,0,0,0,0,0,0 }, // 8 { 0,0,0,0,0,0,0 }, // 9 { 0,0,0,0,0,0,0 }, // 10 { 0,0,0,0,0,0,0 }, // 11 { 0,0,0,0,0,0,0 }, // 12 { 0,0,0,0,0,0,0 }, // 13 { 0,0,0,0,0,0,0 }, // 14 { 0,0,0,0,0,0,0 }, // 15 { 0,0,0,0,0,0,0 }, // 16 { 0,0,0,0,0,0,0 }, // 17 { 0,0,0,0,0,0,0 }, // 18 { 0,0,0,0,0,0,0 }, // 19 { 0,0,0,0,0,0,0 }, // 20 { 0,0,0,0,0,0,0 }, // 21 { 0,0,0,0,0,0,0 }, // 22 { 0,0,0,0,0,0,0 }, // 23 { 0,0,0,0,0,0,0 }, // 24 { 0,0,0,0,0,0,0 }, // 25 { 0,0,0,0,0,0,0 }, // 26 { 0,0,0,0,0,0,0 }, // 27 { 0,0,0,0,0,0,0 }, // 28 { 0,0,0,0,0,0,0 }, // 29 { 0,0,0,0,0,0,0 }, // 30 { 0,0,0,0,0,0,0 }, // 31 { 3, 0, 0, 0, 0, 0, 0 }, // Space { 3, 47, 0, 0, 0, 0, 0 }, // ! { 4, 3, 0, 3, 0, 0, 0 }, // " { 6, 20, 62, 20, 62, 20, 0 }, // # { 6, 4, 42, 107, 42, 16, 0 }, // $ { 6, 38, 22, 8, 52, 50, 0 }, // % { 6, 26, 37, 37, 26, 40, 0 }, // & { 3, 2, 1, 0, 0, 0, 0 }, // ' { 3, 30, 33, 0, 0, 0, 0 }, // ( { 3, 33, 30, 0, 0, 0, 0 }, // ) { 6, 42, 28, 62, 28, 42, 0 }, // * { 6, 8, 8, 62, 8, 8, 0 }, // + { 3, 64, 32, 0, 0, 0, 0 }, // , { 6, 8, 8, 8, 8, 8, 0 }, // - { 3, 32, 0, 0, 0, 0, 0 }, // . { 4, 48, 12, 3, 0, 0, 0 }, // / { 5, 30, 37, 35, 30, 0, 0 }, // 0 { 5, 4, 34, 63, 32, 0, 0 }, // 1 { 5, 34, 49, 41, 38, 0, 0 }, // 2 { 5, 18, 33, 37, 26, 0, 0 }, // 3 { 5, 8, 12, 10, 63, 0, 0 }, // 4 { 5, 23, 37, 37, 25, 0, 0 }, // 5 { 5, 30, 37, 37, 24, 0, 0 }, // 6 { 5, 1, 57, 5, 3, 0, 0 }, // 7 { 5, 26, 37, 37, 26, 0, 0 }, // 8 { 5, 18, 37, 37, 30, 0, 0 }, // 9 { 3, 54, 0, 0, 0, 0, 0 }, // : { 3, 96, 54, 0, 0, 0, 0 }, // ; { 4, 8, 20, 34, 0, 0, 0 }, // < { 5, 20, 20, 20, 20, 0, 0 }, // = { 4, 34, 20, 8, 0, 0, 0 }, // > { 6, 2, 1, 41, 5, 2, 0 }, // ? { 6, 30, 33, 45, 41, 6, 0 }, // @ { 5, 62, 5, 5, 62, 0, 0 }, // A { 5, 63, 37, 37, 26, 0, 0 }, // B { 5, 30, 33, 33, 18, 0, 0 }, // C { 5, 63, 33, 33, 30, 0, 0 }, // D { 5, 63, 37, 37, 33, 0, 0 }, // E { 5, 63, 5, 5, 1, 0, 0 }, // F { 5, 30, 33, 41, 26, 0, 0 }, // G { 5, 63, 4, 4, 63, 0, 0 }, // H { 4, 33, 63, 33, 0, 0, 0 }, // I { 5, 33, 65, 65, 63, 0, 0 }, // J { 5, 63, 12, 18, 33, 0, 0 }, // K { 5, 63, 32, 32, 32, 0, 0 }, // L { 6, 63, 2, 4, 2, 63, 0 }, // M { 5, 63, 6, 24, 63, 0, 0 }, // N { 5, 30, 33, 33, 30, 0, 0 }, // O { 5, 63, 5, 5, 2, 0, 0 }, // P { 5, 30, 33, 17, 46, 0, 0 }, // Q { 5, 63, 13, 21, 34, 0, 0 }, // R { 5, 18, 37, 37, 24, 0, 0 }, // S { 4, 1, 63, 1, 0, 0, 0 }, // T { 5, 31, 32, 32, 31, 0, 0 }, // U { 6, 3, 12, 48, 12, 3, 0 }, // V { 6, 31, 32, 16, 32, 31, 0 }, // W { 6, 49, 10, 4, 10, 49, 0 }, // X { 6, 1, 2, 60, 2, 1, 0 }, // Y { 5, 49, 41, 37, 35, 0, 0 }, // Z { 3, 63, 33, 0, 0, 0, 0 }, // [ { 6, 2, 4, 8, 16, 32, 0 }, // Backslash { 3, 33, 63, 0, 0, 0, 0 }, // ] { 4, 2, 1, 2, 0, 0, 0 }, // ^ { 5, 64, 64, 64, 64, 0, 0 }, // _ { 3, 1, 2, 0, 0, 0, 0 }, // ´ { 5, 24, 36, 36, 56, 0, 0 }, // a { 5, 63, 36, 36, 24, 0, 0 }, // b { 4, 24, 36, 36, 0, 0, 0 }, // c { 5, 24, 36, 36, 63, 0, 0 }, // d { 5, 24, 44, 44, 40, 0, 0 }, // e { 4, 16, 126, 17, 0, 0, 0 }, // f { 5, 8, 84, 84, 40, 0, 0 }, // g { 5, 63, 4, 4, 56, 0, 0 }, // h { 3, 29, 32, 0, 0, 0, 0 }, // i { 4, 64, 64, 61, 0, 0, 0 }, // j { 5, 63, 8, 20, 34, 0, 0 }, // k { 3, 31, 32, 0, 0, 0, 0 }, // l { 6, 60, 4, 60, 4, 56, 0 }, // m { 5, 60, 4, 4, 56, 0, 0 }, // n { 5, 24, 36, 36, 24, 0, 0 }, // o { 5, 124, 36, 36, 24, 0, 0 }, // p { 5, 24, 36, 36, 124, 0, 0 }, // q { 4, 60, 4, 8, 0, 0, 0 }, // r { 5, 40, 44, 44, 20, 0, 0 }, // s { 4, 4, 30, 36, 0, 0, 0 }, // t { 5, 28, 32, 32, 60, 0, 0 }, // u { 5, 12, 48, 48, 12, 0, 0 }, // v { 6, 28, 32, 28, 32, 28, 0 }, // w { 5, 36, 24, 24, 36, 0, 0 }, // x { 5, 12, 80, 80, 60, 0, 0 }, // y { 5, 36, 52, 44, 36, 0, 0 }, // z { 4, 4, 30, 33, 0, 0, 0 }, // { { 4, 0, 63, 0, 0, 0, 0 }, // | { 4, 33, 30, 4, 0, 0, 0 }, // } { 5, 2, 1, 2, 1, 0, 0 }, // ~ { 6, 85, 170, 85, 170, 85, 170 } // 127 }; void setColor(int color) { internalColor = color; } /* * our current LCDAdapter just acts like a parallel port. * To generate the required falling-edge on the E (clk) pin, * we write the actual command argument twice, first with E * asserted and right again with E deasserted. */ inline void command(int value) { int *adr; adr = (int*) BASEADDR; *adr = value | ENAMASK; *adr = value & ~ENAMASK; *adr = value | ENAMASK; } void enableDisplay(int on) { command(DISPLAYON | on); } void clearDisplay() { int x=0; int y=0; int *adr; command( SETBYTEADR ); for (y=0; y<8; y++) { command( SETPAGEADR | y ); for (x=0; x<64; x++) { command( WRITE ); } } } /** draw the least significant byte of 'value' at the given position */ void drawByte( int x, int y, int value ) { // int page = y >> 3; int chip = (x >= 64) ? CHIP2 : CHIP1; command(SETPAGEADR | y); // page command(SETBYTEADR | x); command(WRITE | chip | (value&0xff) ); } void setPixel(int x, int y) { int page = y >> 3; int bit = y & 7; int writeval = 1 << bit; int chip = (x >= 64) ? CHIP2 : CHIP1; command(SETPAGEADR | page); command(SETBYTEADR | x); command(WRITE | chip | writeval); } void horizLine(int x, int y, int length) { int page = y >> 3; int bit = y & 7; int writeval = 1 << bit; int i=0; command(SETPAGEADR | page); command(SETBYTEADR | x); for (i=0; i> 3; int startBit = y & 7; int endPage = (y+length) >> 3; int endBit = (y+length) & 7; int startval = 0; int writeval = 0xff; int endval = 0; int i=0; if (startPage == endPage) { writeval = (1 << endBit) - (1 << startBit); command(SETBYTEADR | x); command(SETPAGEADR | startPage); command(WRITE | CHIP1 | writeval); } else { startval = 0x100 - (1 << startBit); endval = (1 << endBit) - 1; command(SETBYTEADR | x); command(SETPAGEADR | startPage); command(WRITE | CHIP1 | startval); for (i=startPage+1; i= 64) { chipselect = CHIP2; x = x & 63; } else { chipselect = CHIP1; } ypos = y; xpos = x; } void text(char *string) { int j; int value; int len; char ch; command(SETBYTEADR | xpos); command(SETPAGEADR | ypos); while (*string) { ch = *string & 127; len = charset[ch][0]; if ((ch == 10) || ((xpos+len >= 64) && (chipselect == CHIP2))) { if (ch != 10) { string--; } len = 64-xpos; for (j=0; j 63) { xpos = 0; command( SETBYTEADR ); chipselect = CHIP2; } } } string++; } } void bigtext(char *string) { int j; int value; int len; char ch; int *adr; adr = (int*) BASEADDR; command(SETBYTEADR | xpos); command(SETPAGEADR | ypos); while (*string) { ch = *string & 127; len = charset[ch][0]; if ((ch == 10) || ((xpos+(len*2) >= 64) && (chipselect == CHIP2))) { if (ch != 10) { string--; } len = 64-xpos; for (j=0; j 63) { xpos = 0; *adr = SETBYTEADR; chipselect = CHIP2; } *adr = WRITE | chipselect | charset[ch][j]; xpos++; if (xpos > 63) { xpos = 0; *adr = SETBYTEADR; chipselect = CHIP2; } } } string++; } }