Fork of Dimiter program. "Wait" commands adjusted and added Arial 10 font.
Fork of KS0108 by
Diff: KS0108.cpp
- Revision:
- 5:e4b50f4c13a8
- Parent:
- 4:bdc04bb2ffc1
- Child:
- 6:7c0770d5639d
--- a/KS0108.cpp Thu Feb 10 03:06:19 2011 +0000 +++ b/KS0108.cpp Mon May 02 19:05:30 2011 +0000 @@ -1,28 +1,3 @@ -/************************************************************************* -Copyright (c) 2010 Dimiter Kentri - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*******************************************************************************/ - -/* - *@Includes - */ #include "KS0108.h" @@ -33,10 +8,11 @@ CS1.output(); CS2.output(); RST.write(0); wait_us(10); - RST.write(1); //reset screen - E.write(0); - ClearScreen(); //clear display - WriteInstruction(LCD_ON, BOTH); //turn on lcd + RST.write(1); //reset screen + E.write(0); + ClearScreen(); //clear display + WriteInstruction(LCD_ON, BOTH); //turn on lcd + Inverted = 0; } @@ -48,7 +24,7 @@ SelectSide(side); //select controller - wait(0.0000003); // 300ns + wait(0.0000003); //wait 300ns E.write(1); DB.output(); DB.write(Command); @@ -72,6 +48,79 @@ E = 0; } +void KS0108::WriteData(unsigned int data) { + unsigned int displayData, yOffset, chip; + + if(Coord.x >= SCREEN_WIDTH) + return; + chip = Coord.x/CHIP_WIDTH; + wait(0.000000450); // 300ns + + if(Coord.x % CHIP_WIDTH == 0 && chip > 0){ + GotoXY(Coord.x, Coord.y); + } + + DI.write(1); // D/I = 1 + RW.write(0); // R/W = 0 + DB.output(); // data port is output + + yOffset = Coord.y%8; + + if(yOffset != 0) { // first page + + displayData = ReadData(); + + DI.write(1); // D/I = 1 + RW.write(0); // R/W = 0 + SelectSide(chip); + DB.output(); + // data port is output + displayData |= data << yOffset; + if(Inverted) displayData = ~displayData; + DB.write(displayData); // write data + wait(0.0000003); // 300ns + E.write(1); + wait(0.0000001); + E.write(0); + + // second page + GotoXY(Coord.x, Coord.y+8); + + displayData = ReadData(); + + DI.write(1); // D/I = 1 + RW.write(0); // R/W = 0 + SelectSide(chip); + + DB.output(); // data port is output + + displayData |= data >> (8-yOffset); + + if(Inverted) + displayData = ~displayData; + DB.write(displayData); // write data + + wait(0.0000003); // 300ns + E.write(1); + wait(0.0000001); + E.write(0); + + GotoXY(Coord.x+1, Coord.y-8); + }else { + + // just this code gets executed if the write is on a single page + if(Inverted) + data = ~data; + wait(0.0000003); // 300nsEN_DELAY(); + DB.write(data); // write data + wait(0.0000003); // 300ns + E = 1; + wait(0.0000001); + E = 0; + Coord.x++; + } +} + void KS0108::WriteDataColPag(unsigned int page, unsigned int col, unsigned int data){ @@ -82,7 +131,7 @@ if(col<(SCREEN_WIDTH/2)){ SelectSide(LEFT); WriteInstruction(LCD_SET_PAGE|page,LEFT); - WriteInstruction(LCD_SET_ADD|col,LEFT); //set page and column position + WriteInstruction(LCD_SET_ADD|col,LEFT); //set page and column position WriteData(data,LEFT); //output data to D0-D7 }else{ @@ -90,19 +139,21 @@ col -= (SCREEN_WIDTH/2); WriteInstruction(LCD_SET_PAGE|page,RIGHT); WriteInstruction(LCD_SET_ADD|col,RIGHT); //set page and column position - WriteData(data,RIGHT); //output data to D0-D7 + WriteData(data,RIGHT); //output data to D0-D7 } SelectSide(NONE); } + unsigned int KS0108::ReadData(){ unsigned int data; DB.input(); - DI.write(1); + DI.write(1); RW.write(1); + E.write(1); wait(0.00000045); @@ -114,7 +165,6 @@ return data; } - unsigned int KS0108::ReadStatus(){ unsigned int status; DB.input(); @@ -131,7 +181,8 @@ DB.output(); return status; -} +} + void KS0108::SelectSide(unsigned char side){ @@ -165,6 +216,7 @@ WriteInstruction(LCD_OFF,BOTH); } + /*******************************************************************************************/ @@ -178,19 +230,19 @@ if(x>=64){ WriteInstruction(LCD_SET_PAGE|(y/8),RIGHT); WriteInstruction(LCD_SET_ADD|x,RIGHT); - position = ReadData(); //dummy read - position = ReadData(); //actual read + position = ReadData(); //dummy read + position = ReadData(); //actual read WriteInstruction(LCD_SET_ADD|x,RIGHT); if(color==WHITE) - WriteData(position&(~(1<<(y%8))),RIGHT); // draw a white pixel + WriteData(position&(~(1<<(y%8))),RIGHT); // draw a white pixel else WriteData(position|(1<<(y%8)),RIGHT); wait_us(450); }else{ WriteInstruction(LCD_SET_PAGE|(y/8),LEFT); WriteInstruction(LCD_SET_ADD|x,LEFT); - position = ReadData(); //dummy read - position = ReadData(); //actual read + position = ReadData(); //dummy read + position = ReadData(); //actual read WriteInstruction(LCD_SET_ADD|x,LEFT); if(color==WHITE) WriteData(position&(~(1<<(y%8))),LEFT); @@ -333,7 +385,7 @@ // If the starting X coordinate is larger than the ending X coordinate, - // swap the start and end coordinates. + // swap coordinates. if(lX1 > lX2){ lError = lX1; lX1 = lX2; @@ -349,7 +401,7 @@ lError = -lDeltaX / 2; // Initialize the error term to negative half the X delta. - if(lY1 < lY2){ // Determine the direction to step in the Y axis when required. + if(lY1 < lY2){ // Determine the direction to step in the Y axis when required. lYStep = 1; }else{ lYStep = -1; @@ -373,11 +425,11 @@ lError += lDeltaY; - if(lError > 0){ // See if the error term is now greater than zero. + if(lError > 0){ // See if the error term is now greater than zero. - lY1 += lYStep; // Take a step in the Y axis. + lY1 += lYStep; // Take a step in the Y axis. - lError -= lDeltaX; // Decrement the error term by the X delta. + lError -= lDeltaX; // Decrement the error term by the X delta. } } } @@ -501,7 +553,7 @@ StoppingX = TwoBSquare*XRadius; StoppingY = 0; - while ( StoppingX >=StoppingY ) //first set of points,y'>-1 + while ( StoppingX >=StoppingY ) //first set of points,y'>-1 { Plot4EllipsePoints(CX,CY,X,Y,color); Y++; @@ -524,7 +576,7 @@ StoppingY = TwoASquare*YRadius; StoppingX = 0; - while ( StoppingY >=StoppingX ) //{2nd set of points, y'< -1} + while ( StoppingY >=StoppingX ) //{2nd set of points, y'< -1} { Plot4EllipsePoints(CX,CY,X,Y,color); X++; @@ -547,8 +599,32 @@ SetPixel(CX-X, CY+Y, color); //{point in quadrant 2} SetPixel(CX-X, CY-Y, color); //{point in quadrant 3} SetPixel(CX+X, CY-Y, color); //{point in quadrant 4} +} + + +void KS0108::RightTriangle ( int topx, int topy, int rightx, int righty) { + + //draw rectangle one line at a time + Line( topx,topy, rightx,righty,BLACK ); //draw hypotenuse + Line ( topx,righty,topx,topy,BLACK); //draw perpendicular + Line (topx,righty, rightx,righty,BLACK); // draw base + } +void KS0108::Triangle ( int topx, int topy, int rightx, int righty) { + int base =0; + base = 2* rightx-topx; + //draw rectangle one line at a time + Line( topx,topy, rightx,righty,BLACK ); //draw hypotenuse + Line ( topx,righty,topx,topy,BLACK); //draw perpendicular + Line(topx-base/2,righty, rightx,righty,BLACK); // draw base + Line(topx-base/2, righty, topx,topy,BLACK); // draw hypotenuse + +} + + + + /***********************************************************************************/ @@ -574,44 +650,58 @@ } } -void KS0108::CustomImage(Image* image,unsigned int x, unsigned int y, unsigned int color){ - unsigned int i, j, bit_idx, pixelByte, imgHeight, imgSize; +unsigned int KS0108::ReadArrayData(const unsigned int* ptr) { + return (*ptr); +} - imgHeight = image->imgHeight; //get height of the image array - imgSize = (image->imgWidth)>>3; //number of bytes = width of icon/8 +void KS0108::DrawBitmap(const unsigned int * bitmap, unsigned int x, unsigned int y, unsigned int color){ +unsigned int width, height; +unsigned int i, j; - for(i=0;i<imgHeight;i++){ - for(j=0;j<imgSize;j++){ - pixelByte = image->imgarray[i*imgSize+j]; - for(bit_idx=0;bit_idx<8;bit_idx++){ - if(pixelByte&(0x80>>bit_idx)) - SetPixel(x+bit_idx+8*j, y+i, color); - else - SetPixel(x+bit_idx+8*j, y+i, !color); - } - } - } -} + width = ReadArrayData(bitmap++); + height = ReadArrayData(bitmap++); + for(j = 0; j < height / 8; j++) { + GotoXY(x, y + (j*8) ); + for(i = 0; i < width; i++) { + unsigned int displayData = ReadArrayData(bitmap++); + if(color == BLACK) + WriteData(displayData); + else + WriteData(~displayData); + } + } +} /******************************************************************************************/ -void KS0108::CursorXY(unsigned int x, unsigned int y){ +void KS0108::GotoXY(unsigned int x, unsigned int y) { + unsigned int chip, cmd; + if( (x > SCREEN_WIDTH-1) || (y > SCREEN_HEIGHT-1) ) // exit if coordinates are not legal - return; + return; + Coord.x = x; // save new coordinates + Coord.y = y; + + if(y/8 != Coord.page) { + Coord.page = y/8; + cmd = LCD_SET_PAGE | Coord.page; // set y address on all chips + for(chip=0; chip < 2; chip++){ + WriteInstruction(cmd, chip); + } + } + chip = Coord.x/64; + x = x % 64; + cmd = LCD_SET_ADD | x; + WriteInstruction(cmd, chip); // set x address on active chip - if(y<(SCREEN_WIDTH/2)){ - SelectSide(LEFT); - WriteInstruction(LCD_SET_PAGE|(y/8),RIGHT); - WriteInstruction(LCD_SET_ADD|x,RIGHT); - }else{ - SelectSide(RIGHT); - WriteInstruction(LCD_SET_PAGE|(y/8),RIGHT); - WriteInstruction(LCD_SET_ADD|x,RIGHT); - } } - -void KS0108::Putc (int page, int col,unsigned char c) { + +/*****************************************************************************************/ + + + +void KS0108::Putchar (int page, int col,unsigned char c) { if (c>31 && c<127){ for(int i=0;i<5;i++){ WriteDataColPag(page,col+i,System5x7[((c-32)*5+i)+6]); @@ -624,15 +714,13 @@ void KS0108::PutString(unsigned int x, unsigned int y,char* str){ while(*str != 0){ - Putc(x,y,*str); + Putchar(x,y,*str); str++; y+=System5x7[2]; } } - - void KS0108::PrintFloat(float val, unsigned int x,unsigned int y){ char buf[20] = {}; // prints up to 20 digits sprintf(buf,"%f",val); @@ -646,3 +734,102 @@ sprintf(buf,"%d",val); PutString(x,y,buf); } + +void KS0108::SelectFont(unsigned int* font,unsigned int color, FontCallback callback) { + Font = font; + FontRead = callback; + FontColor = color; +} + + +int KS0108::PrintChar(char c) { + unsigned int width = 0; + unsigned int height = FontRead(Font+FONT_HEIGHT); + unsigned int bytes = (height+7)/8; + + unsigned int firstChar = FontRead(Font+FONT_FIRST_CHAR); + unsigned int charCount = FontRead(Font+FONT_CHAR_COUNT); + + unsigned int index = 0; + unsigned int x=Coord.x , y=Coord.y; + + if(c < firstChar || c >= (firstChar+charCount)) { + return 1; + } + c-= firstChar; + + if( FontRead(Font+FONT_LENGTH) == 0 && FontRead(Font+FONT_LENGTH+1) == 0) { + // zero length is flag indicating fixed width font (array does not contain width data entries) + width = FontRead(Font+FONT_FIXED_WIDTH); + index = c*bytes*width+FONT_WIDTH_TABLE; + } + else{ + // variable width font, read width data, to get the index + for(unsigned int i=0; i<c; i++) { + index += FontRead(Font+FONT_WIDTH_TABLE+i); + } + index = index*bytes+charCount+FONT_WIDTH_TABLE; + width = FontRead(Font+FONT_WIDTH_TABLE+c); + } + + // last but not least, draw the character + for(unsigned int i=0; i<bytes; i++) { + unsigned int page = i*width; + for(unsigned int j=0; j<width; j++) { + unsigned int data = FontRead(Font+index+page+j); + + if(height > 8 && height < (i+1)*8) { + data >>= (i+1)*8-height; + } + + WriteData(data); + + } + // 1px gap between chars + WriteData(0x00); + GotoXY(x,Coord.y+8); + + } + GotoXY(x+width+1, y); + + + return 0; +} + +void KS0108::PrintString(char* str) { + int x = Coord.x; + while(*str != 0) { + if(*str == '\n') { + GotoXY(x, Coord.y+ FontRead(Font+FONT_HEIGHT)); + } else { + PrintChar(*str); + } + str++; + } +} + +void KS0108::PrintNumber(long n){ + char buf[10]; // prints up to 10 digits + char i=0; + if(n==0) + PrintChar('0'); + else{ + if(n < 0){ + PrintChar('-'); + n = -n; + } + while(n>0 && i <= 10){ + buf[i++] = n % 10; // n % base + n /= 10; // n/= base + } + for(; i >0; i--) + PrintChar((char) (buf[i-1] < 10 ? '0' + buf[i-1] : 'A' + buf[i-1] - 10)); + } +} + + + + + + +