Dependents:   Display bigthingRec bigthingRecfinal

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers KS0108.cpp Source File

KS0108.cpp

00001 #include "KS0108.h"     
00002 
00003 
00004 KS0108::KS0108 (PinName _RST,PinName _DI, PinName _RW, PinName _E, PinName _CS2, PinName _CS1, PinName DB0, PinName DB1, PinName DB2, PinName DB3, PinName DB4, PinName DB5, PinName DB6, PinName DB7)
00005     : DB(DB0,DB1,DB2,DB3,DB4,DB5,DB6,DB7),RST (_RST),DI(_DI), RW(_RW), E(_E), CS2(_CS2), CS1(_CS1) {
00006    
00007     DB.output();      
00008     CS1.output(); CS2.output();    
00009     RST.write(0);
00010     wait_us(10);  
00011     RST.write(1);                         //reset screen
00012     E.write(0);                       
00013     ClearScreen();                      //clear display
00014     WriteInstruction(LCD_ON, BOTH);     //turn on lcd  
00015     Inverted = 0;     
00016 }
00017 
00018 
00019 
00020 void  KS0108::WriteInstruction(unsigned int Command,unsigned int side){
00021     E.write(0); 
00022     DI.write(0);
00023     RW.write(0);
00024         
00025     SelectSide(side);   //select controller
00026 
00027     wait(0.0000003);     //wait 300ns
00028     E.write(1);
00029     DB.output();
00030     DB.write(Command);        
00031     wait(0.0000001);
00032     E.write(0);
00033 }
00034 
00035 
00036 void  KS0108::WriteData(unsigned int data,unsigned char side){
00037     E.write(0); 
00038     DI.write(1);
00039     RW.write(0);
00040     
00041     SelectSide(side);
00042 
00043     wait(0.0000003); // 300ns
00044     E = 1;
00045     DB.output();
00046     DB.write(data);     
00047     wait(0.0000001);
00048     E = 0;
00049 }
00050 
00051 void KS0108::WriteData(unsigned int data) {
00052     unsigned int displayData, yOffset, chip;
00053     
00054     if(Coord.x >= SCREEN_WIDTH)
00055         return;
00056      chip = Coord.x/CHIP_WIDTH; 
00057      wait(0.000000450); // 300ns     
00058 
00059      if(Coord.x % CHIP_WIDTH == 0 && chip > 0){         
00060      GotoXY(Coord.x, Coord.y);
00061      }
00062 
00063     DI.write(1);                    // D/I = 1
00064     RW.write(0);                      // R/W = 0    
00065     DB.output();                    // data port is output
00066     
00067     yOffset = Coord.y%8;
00068 
00069     if(yOffset != 0) {                 // first page
00070 
00071     displayData = ReadData();
00072 
00073     DI.write(1);                            // D/I = 1
00074     RW.write(0);                              // R/W = 0    
00075     SelectSide(chip);    
00076     DB.output();
00077                                             // data port is output             
00078     displayData |= data << yOffset;
00079     if(Inverted)    displayData = ~displayData;
00080     DB.write(displayData);                     // write data
00081     wait(0.0000003);                         // 300ns
00082     E.write(1);
00083     wait(0.0000001);
00084     E.write(0);
00085         
00086                                     // second page
00087     GotoXY(Coord.x, Coord.y+8);
00088         
00089     displayData = ReadData();
00090 
00091     DI.write(1);                            // D/I = 1
00092     RW.write(0);                              // R/W = 0    
00093     SelectSide(chip);
00094 
00095     DB.output();                // data port is output
00096         
00097     displayData |= data >> (8-yOffset);
00098     
00099         if(Inverted)
00100             displayData = ~displayData;
00101             DB.write(displayData);        // write data
00102            
00103             wait(0.0000003);             // 300ns
00104             E.write(1);
00105             wait(0.0000001);
00106             E.write(0);
00107         
00108         GotoXY(Coord.x+1, Coord.y-8);
00109     }else    {
00110 
00111         // just this code gets executed if the write is on a single page
00112         if(Inverted)
00113             data = ~data;      
00114         wait(0.0000003);                 // 300nsEN_DELAY();
00115         DB.write(data);                    // write data
00116         wait(0.0000003);                 // 300ns
00117            E = 1;
00118            wait(0.0000001);
00119         E = 0;
00120         Coord.x++; 
00121     }
00122 }
00123 
00124 
00125 void KS0108::WriteDataColPag(unsigned int page, unsigned int col,  unsigned int data){
00126     
00127     SelectSide(NONE);  
00128     col     = col%SCREEN_WIDTH;
00129     page    = page%8;
00130 
00131     if(col<(SCREEN_WIDTH/2)){
00132     SelectSide(LEFT);           
00133     WriteInstruction(LCD_SET_PAGE|page,LEFT);     
00134     WriteInstruction(LCD_SET_ADD|col,LEFT);          //set page and column position
00135     WriteData(data,LEFT);                            //output data to D0-D7
00136     }else{
00137     
00138     SelectSide(RIGHT);
00139     col -= (SCREEN_WIDTH/2);     
00140     WriteInstruction(LCD_SET_PAGE|page,RIGHT);     
00141     WriteInstruction(LCD_SET_ADD|col,RIGHT);        //set page and column position
00142     WriteData(data,RIGHT);                          //output data to D0-D7
00143     }    
00144                            
00145     SelectSide(NONE);
00146 }
00147 
00148 
00149 
00150 unsigned int KS0108::ReadData(){
00151    unsigned int data;
00152    DB.input();
00153 
00154    DI.write(1);     
00155    RW.write(1);
00156 
00157    E.write(1);
00158    wait(0.00000045);
00159       
00160    data = DB.read();
00161    wait(0.0000001);
00162    E.write(0);   
00163    DB.output();
00164    
00165    return data;     
00166 }
00167 
00168 unsigned int KS0108::ReadStatus(){
00169    unsigned int status;
00170    DB.input();
00171  
00172    DI.write(0);
00173    
00174    RW.write(1);
00175    E.write(1);
00176    wait(0.00000045);
00177       
00178    status = DB.read();
00179    E.write(0);
00180    wait(0.0000001);
00181    DB.output();
00182    
00183    return status;     
00184 }                    
00185 
00186 
00187 
00188 void KS0108::SelectSide(unsigned char side){
00189     if(side==LEFT)
00190         {CS1.write(1);CS2.write(0);}
00191     else if(side==RIGHT)
00192         {CS1.write(0);CS2.write(1);}
00193     else if (side==BOTH)
00194         {CS1.write(1);CS2.write(1);}
00195     else if (side==NONE)
00196         {CS1.write(0);CS2.write(0);}
00197 }
00198 
00199 
00200 void KS0108::ClearScreen(){
00201      for (int col=0;col<128;col++) {
00202         for (int page=0;page<8;page++)
00203         {
00204             WriteDataColPag(page,col,WHITE);
00205         }
00206     }
00207 }     
00208 
00209 
00210 void KS0108::TurnOn(){
00211     WriteInstruction(LCD_ON,BOTH);
00212 }
00213 
00214 
00215 void KS0108::TurnOff(){
00216     WriteInstruction(LCD_OFF,BOTH);
00217 }
00218 
00219 
00220 /*******************************************************************************************/      
00221 
00222  
00223 void KS0108::SetPixel(unsigned int x,  unsigned int y,  unsigned int color){    
00224   
00225   unsigned int position;
00226    
00227   SelectSide(NONE);
00228   WriteInstruction(LCD_SET_ADD,NONE);    
00229   
00230   if(x>=64){           
00231   WriteInstruction(LCD_SET_PAGE|(y/8),RIGHT);
00232   WriteInstruction(LCD_SET_ADD|x,RIGHT);
00233   position = ReadData();                            //dummy read 
00234   position = ReadData();                            //actual read 
00235   WriteInstruction(LCD_SET_ADD|x,RIGHT);
00236   if(color==WHITE)                                
00237   WriteData(position&(~(1<<(y%8))),RIGHT);         // draw a white pixel
00238   else                                            
00239   WriteData(position|(1<<(y%8)),RIGHT);
00240   wait_us(450);
00241   }else{ 
00242   WriteInstruction(LCD_SET_PAGE|(y/8),LEFT);
00243   WriteInstruction(LCD_SET_ADD|x,LEFT);  
00244   position = ReadData();                            //dummy read 
00245   position = ReadData();                            //actual read 
00246   WriteInstruction(LCD_SET_ADD|x,LEFT);
00247   if(color==WHITE)                                
00248   WriteData(position&(~(1<<(y%8))),LEFT);              
00249   else                                            
00250   WriteData(position|(1<<(y%8)),LEFT);
00251   
00252   wait_us(450);
00253 
00254   }
00255 
00256 }       
00257 
00258 
00259 
00260 void KS0108::FullRectangle(unsigned int Xaxis1, unsigned int Yaxis1, unsigned int Xaxis2 ,unsigned int Yaxis2,unsigned int color){
00261            
00262     for(unsigned int i=Xaxis1;i<=Xaxis2;i++){
00263         for(unsigned int j=Yaxis1;j<=Yaxis2;j++){
00264             SetPixel(i,j,color);
00265         } 
00266     }   
00267 }
00268 
00269 void KS0108::ReverseFullRectangle(unsigned int Xaxis1, unsigned int Yaxis1, unsigned int Xaxis2 ,unsigned int Yaxis2,unsigned int color){
00270            
00271     for(unsigned int i=Xaxis2;i<=Xaxis1;i--){
00272         for(unsigned int j=Yaxis2;j<=Yaxis1;j--){
00273             SetPixel(i,j,color);
00274         } 
00275     }   
00276 }  
00277 
00278 
00279 void KS0108::EmptyRectangle(unsigned int Xaxis1,unsigned int Yaxis1, unsigned int Xaxis2,unsigned int Yaxis2,unsigned int color){
00280       unsigned int CurrentValue;
00281 
00282     /* Draw the two horizontal lines */
00283       for (CurrentValue = 0; CurrentValue < Xaxis2 - Xaxis1+ 1; CurrentValue++) 
00284       {
00285         SetPixel(Xaxis1 + CurrentValue, Yaxis1,color);
00286         SetPixel(Xaxis1 + CurrentValue, Yaxis2,color);
00287     }
00288       
00289       /* draw the two vertical lines */
00290       for (CurrentValue = 0; CurrentValue < Yaxis2 - Yaxis1 + 1; CurrentValue++)    
00291       {
00292         SetPixel(Xaxis1, Yaxis1 + CurrentValue,color);
00293         SetPixel(Xaxis2, Yaxis1 + CurrentValue,color);
00294     }
00295 }
00296 
00297 
00298 void KS0108::RoundRectangle(unsigned int x, unsigned int y, unsigned int width, unsigned int height, unsigned int radius, unsigned int color) {
00299       int tSwitch, x1 = 0, y1 = radius;
00300       tSwitch = 3 - 2 * radius;
00301     
00302     while (x1 <= y1) {
00303         SetPixel(x+radius - x1, y+radius - y1, color);
00304         SetPixel(x+radius - y1, y+radius - x1, color);
00305 
00306         SetPixel(x+width-radius + x1, y+radius - y1, color);
00307         SetPixel(x+width-radius + y1, y+radius - x1, color);
00308         
00309         SetPixel(x+width-radius + x1, y+height-radius + y1, color);
00310         SetPixel(x+width-radius + y1, y+height-radius + x1, color);
00311 
00312         SetPixel(x+radius - x1, y+height-radius + y1, color);
00313         SetPixel(x+radius - y1, y+height-radius + x1, color);
00314 
00315         if (tSwitch < 0) {
00316             tSwitch += (4 * x1 + 6);
00317         } else {
00318             tSwitch += (4 * (x1 - y1) + 10);
00319             y1--;
00320         }
00321         x1++;
00322     }
00323           
00324     HLineShort(x+radius,y, width-(2*radius), color);                // top
00325     HLineShort(x+radius,y+height, width-(2*radius),  color);        // bottom
00326     VLineShort(x,y+radius,height-(2*radius), color);                // left
00327     VLineShort(x+width, y+radius,height-(2*radius),  color);        // right
00328 }
00329 
00330 
00331 void KS0108::HLine(unsigned int Xaxis1, unsigned int Xaxis2 ,unsigned int Yaxis,unsigned int color){
00332     FullRectangle(Xaxis1,Yaxis,Xaxis2,Yaxis,color);
00333 
00334 }
00335 
00336 
00337 void KS0108::HLineShort(unsigned int Xaxis, unsigned int Yaxis,unsigned int width ,unsigned int color){
00338     FullRectangle(Xaxis,Yaxis,Xaxis+width,Yaxis,color);
00339 
00340 } 
00341 
00342 
00343 void KS0108::VLine(unsigned int Xaxis, unsigned int Yaxis1 ,unsigned int Yaxis2,unsigned int color){
00344     FullRectangle(Xaxis,Yaxis1,Xaxis,Yaxis2,color);    
00345 }
00346 
00347 
00348 void KS0108::VLineShort(unsigned int Xaxis,unsigned int Yaxis, unsigned int height ,unsigned int color){
00349     FullRectangle(Xaxis,Yaxis,Xaxis,Yaxis+height,color);
00350 
00351 }
00352 
00353 
00354 void KS0108::DegreeLine(unsigned int x, int y,unsigned int degree,unsigned int inner_radius,unsigned int outer_radius, unsigned int color){
00355   int fx,fy,tx,ty;
00356   fx = x + dfloor(inner_radius * sin(degree * 3.14 / 180));
00357   fy = y - dfloor(inner_radius * cos(degree * 3.14 / 180));
00358   tx = x + dfloor(outer_radius * sin(degree * 3.14 / 180));
00359   ty = y - dfloor(outer_radius * cos(degree * 3.14 / 180));
00360   SlantyLine(fx,fy,tx,ty,color);
00361 }
00362 
00363 
00364 double KS0108::dfloor( double value ) {
00365   
00366   if (value < 0.0)
00367     return ceil( value );
00368   else
00369     return floor( value );
00370     
00371 }
00372 
00373 
00374 void KS0108::SlantyLine(unsigned int lX1, unsigned int lY1, unsigned int lX2,unsigned int lY2,unsigned int color){
00375     long lError, lDeltaX, lDeltaY, lYStep, bSteep;       
00376     
00377     // A steep line has a bigger ordinate.
00378     
00379     if(((lY2 > lY1) ? (lY2 - lY1) : (lY1 - lY2)) > ((lX2 > lX1) ? (lX2 - lX1) : (lX1 - lX2))){
00380         bSteep = 1;
00381     }else {
00382         bSteep = 0;
00383     }
00384         
00385     // If line is steep, swap the X and Y coordinates.
00386     if(bSteep){
00387         lError = lX1;
00388         lX1 = lY1;
00389         lY1 = lError;
00390         lError = lX2;
00391         lX2 = lY2;
00392         lY2 = lError;
00393     }
00394 
00395    
00396     // If the starting X coordinate is larger than the ending X coordinate,
00397     // swap coordinates.
00398     if(lX1 > lX2){
00399         lError = lX1;
00400         lX1 = lX2;
00401         lX2 = lError;
00402         lError = lY1;
00403         lY1 = lY2;
00404         lY2 = lError;
00405     }
00406         
00407     // Compute the difference between the start and end coordinates.      
00408     lDeltaX = lX2 - lX1;
00409     lDeltaY = (lY2 > lY1) ? (lY2 - lY1) : (lY1 - lY2);
00410                                                                    
00411     lError = -lDeltaX / 2;          // Initialize the error term to negative half the X delta.
00412      
00413     if(lY1 < lY2){                   // Determine the direction to step in the Y axis when required.
00414         lYStep = 1;
00415     }else{
00416         lYStep = -1;
00417     }
00418         
00419     for(; lX1 <= lX2; lX1++){    // Loop through all the points along the X axis of the line.
00420         
00421         // See if this is a steep line.
00422         
00423         if(bSteep){
00424             
00425             // Plot this point of the line, swapping the X and Y coordinates.
00426             
00427             SetPixel(lY1, lX1,color);
00428         }
00429         else {           // Plot this point of the line, using the coordinates as is.            
00430             SetPixel(lX1, lY1,color);
00431         }                     
00432         
00433         // Increment the error term by the Y delta.
00434         
00435         lError += lDeltaY; 
00436                     
00437         if(lError > 0){                // See if the error term is now greater than zero.
00438                      
00439             lY1 += lYStep;            // Take a step in the Y axis.
00440                                                                        
00441             lError -= lDeltaX;         // Decrement the error term by the X delta.
00442         }
00443     }
00444 }
00445 
00446 
00447 
00448 void KS0108::Line(unsigned int x1, unsigned int  y1, unsigned int  x2, unsigned int  y2, unsigned int color){
00449 unsigned int  deltax, deltay, x,y, steep;
00450 int lerror, ystep;
00451 
00452     steep = absDiff(y1,y2) > absDiff(x1,x2);   //check slope
00453 
00454     if ( steep ){
00455         swap(x1, y1);
00456         swap(x2, y2);
00457     }
00458 
00459     if (x1 > x2){
00460         swap(x1, x2);
00461         swap(y1, y2);
00462     }
00463 
00464     deltax = x2 - x1;
00465     deltay = absDiff(y2,y1);  
00466     lerror = deltax / 2;
00467     y = y1;
00468     if(y1 < y2) ystep = 1;  else ystep = -1;
00469 
00470     for(x = x1; x <= x2; x++){
00471         if (steep) SetPixel(y,x, color); else SetPixel(x,y, color);
00472            lerror -= deltay;
00473         if (lerror < 0){
00474             y = y + ystep;
00475             lerror += deltax;
00476         }
00477     }
00478 }
00479 
00480 
00481 void KS0108::EmptyCircle(unsigned int CenterX, unsigned int CenterY, unsigned int Radius,unsigned int color){
00482   unsigned int y=0, x=0, d = 0;
00483   int part; 
00484   d = CenterY - CenterX;
00485   y = Radius;
00486   part = 3 - 2 * Radius;
00487 
00488   while (x <= y) { 
00489     SetPixel(CenterX + x, CenterY + y,color);  
00490     SetPixel(CenterX + x, CenterY - y,color);
00491     SetPixel(CenterX - x, CenterY + y,color);    
00492     SetPixel(CenterX - x, CenterY - y,color);
00493     SetPixel(CenterY + y - d, CenterY + x,color); 
00494     SetPixel(CenterY + y - d, CenterY - x,color);
00495     SetPixel(CenterY - y - d, CenterY + x,color);
00496     SetPixel(CenterY - y - d, CenterY - x,color); 
00497 
00498     if (part < 0) part += (4 * x + 6);
00499     else {
00500       part += (4 * (x - y) + 10);
00501       y--;
00502     }
00503     x++;
00504   }
00505 
00506 }  
00507 
00508  
00509 void KS0108::FullCircle(unsigned int CenterX, unsigned int CenterY, unsigned int Radius,unsigned int color){  
00510 
00511 int f = 1 - Radius;
00512 int ddF_x = 1;
00513 int ddF_y = 2 * Radius;             //changed sign of -2
00514 unsigned int x = 0;
00515 unsigned int y = Radius;      
00516     
00517      //Fill in the center between the two halves
00518      
00519     Line(CenterX, CenterY-Radius, CenterX, CenterY+Radius, color);
00520  
00521     while(x < y){
00522         if(f >= 0)
00523         {
00524             y--;
00525             ddF_y += 2;
00526             f += ddF_y;
00527         }
00528         x++;
00529         ddF_x += 2;
00530         f += ddF_x;    
00531 
00532         /*
00533          * Now draw vertical lines between the points on the circle rather than
00534          * draw the points of the circle. This draws lines between the 
00535          * perimeter points on the upper and lower quadrants of the 2 halves of the circle.
00536          */
00537 
00538         Line(CenterX+x, CenterY+y, CenterX+x, CenterY-y, color);
00539         Line(CenterX-x, CenterY+y, CenterX-x, CenterY-y, color);
00540         Line(CenterX+y, CenterY+x, y+CenterX, CenterY-x, color);
00541         Line(CenterX-y, CenterY+x, CenterX-y, CenterY-x, color);
00542       }
00543 }                 
00544 
00545 
00546 
00547 void KS0108::PlotEllipse(long CX, long  CY, long XRadius,long YRadius, int color) {
00548 
00549 
00550   long X, Y;
00551   long XChange, YChange;
00552   long EllipseError;
00553   long TwoASquare,TwoBSquare;
00554   long StoppingX, StoppingY;
00555   TwoASquare = 2*XRadius*XRadius;
00556   TwoBSquare = 2*YRadius*YRadius;
00557   X = XRadius;
00558   Y = 0;
00559   XChange = YRadius*YRadius*(1-2*XRadius);
00560   YChange = XRadius*XRadius;
00561   EllipseError = 0;
00562   StoppingX = TwoBSquare*XRadius;
00563   StoppingY = 0;
00564 
00565   while ( StoppingX >=StoppingY )                 //first set of points,y'>-1
00566   {
00567     Plot4EllipsePoints(CX,CY,X,Y,color);
00568     Y++;
00569     StoppingY=StoppingY+ TwoASquare;
00570     EllipseError = EllipseError+ YChange;
00571     YChange=YChange+TwoASquare;
00572     if ((2*EllipseError + XChange) > 0 ) {
00573       X--;
00574       StoppingX=StoppingX- TwoBSquare;
00575       EllipseError=EllipseError+ XChange;
00576       XChange=XChange+TwoBSquare;
00577     }
00578   }
00579 
00580   Y = YRadius;
00581   X = 0;
00582   YChange = XRadius*XRadius*(1-2*YRadius);
00583   XChange = YRadius*YRadius;
00584   EllipseError = 0;
00585   StoppingY = TwoASquare*YRadius;
00586   StoppingX = 0;
00587 
00588   while ( StoppingY >=StoppingX )                 //{2nd set of points, y'< -1}
00589   {
00590     Plot4EllipsePoints(CX,CY,X,Y,color);
00591     X++;
00592     StoppingX=StoppingX + TwoBSquare;
00593     EllipseError=EllipseError+ XChange;
00594     XChange=XChange+TwoBSquare;
00595     if ((2*EllipseError + YChange) > 0 ) {
00596       Y--;
00597       StoppingY=StoppingY- TwoASquare;
00598       EllipseError=EllipseError+ YChange;
00599       YChange=YChange+TwoASquare;
00600     }
00601   }
00602 } 
00603 
00604 
00605 
00606 void KS0108::Plot4EllipsePoints(long CX,long  CY, long X, long Y, int color){
00607   SetPixel(CX+X, CY+Y, color); //{point in quadrant 1}
00608   SetPixel(CX-X, CY+Y, color); //{point in quadrant 2}
00609   SetPixel(CX-X, CY-Y, color); //{point in quadrant 3}
00610   SetPixel(CX+X, CY-Y, color); //{point in quadrant 4}
00611 }                                                        
00612 
00613 
00614 void KS0108::RightTriangle ( int topx, int topy, int rightx, int righty) {
00615 
00616     //draw rectangle one line at a time
00617     Line( topx,topy, rightx,righty,BLACK );        //draw hypotenuse
00618     Line ( topx,righty,topx,topy,BLACK);         //draw perpendicular
00619     Line (topx,righty, rightx,righty,BLACK);      // draw base
00620     
00621 }
00622 
00623 void KS0108::Triangle ( int topx, int topy, int rightx, int righty) {
00624     int base =0;
00625     base = 2* rightx-topx;
00626     //draw rectangle one line at a time
00627     Line( topx,topy, rightx,righty,BLACK );                //draw hypotenuse
00628     Line ( topx,righty,topx,topy,BLACK);                     //draw perpendicular
00629     Line(topx-base/2,righty, rightx,righty,BLACK);         // draw base
00630     Line(topx-base/2, righty, topx,topy,BLACK);            // draw hypotenuse
00631     
00632 }
00633 
00634 
00635 
00636 
00637 /***********************************************************************************/
00638 
00639 
00640 void KS0108::FullScreenBMP (unsigned char *PictureData){
00641     unsigned int Page=0;
00642       unsigned int Column=0;
00643       
00644     // Draw left side of the picture 
00645     SelectSide(LEFT);
00646       for (Page = 0; Page < 8; Page++){                     /* loop on the 8 pages */            
00647               WriteInstruction(LCD_SET_PAGE | Page,LEFT); /* Set the page */
00648               for (Column = 0; Column < 64; Column++)
00649             WriteData(PictureData[(128*Page)+Column],LEFT);
00650     }
00651     
00652     // Draw right side of the picture
00653     SelectSide(RIGHT);
00654       for (Page = 0; Page < 8; Page++){                     /* loop on the 8 pages */
00655     
00656               WriteInstruction(LCD_SET_PAGE| Page,RIGHT); /* Set the page */
00657               for (Column = 64; Column < 128; Column++)
00658             WriteData(PictureData[(128*Page)+Column],RIGHT);
00659     }    
00660 }
00661 
00662 unsigned int KS0108::ReadArrayData(const unsigned int* ptr) { 
00663     return (*ptr);
00664 }
00665 
00666 void KS0108::DrawBitmap(const unsigned int * bitmap, unsigned int x, unsigned int y, unsigned int color){
00667 unsigned int width, height;
00668 unsigned int i, j;
00669 
00670   width = ReadArrayData(bitmap++); 
00671   height = ReadArrayData(bitmap++);
00672   for(j = 0; j < height / 8; j++) {
00673      GotoXY(x, y + (j*8) );
00674      for(i = 0; i < width; i++) {
00675          unsigned int displayData = ReadArrayData(bitmap++);
00676             if(color == BLACK)
00677             WriteData(displayData);
00678          else
00679             WriteData(~displayData);
00680      }
00681   }
00682 }  
00683 /******************************************************************************************/
00684 
00685 
00686 void KS0108::GotoXY(unsigned int x, unsigned int y) {
00687   unsigned int chip, cmd;
00688     
00689   if( (x > SCREEN_WIDTH-1) || (y > SCREEN_HEIGHT-1) )    // exit if coordinates are not legal
00690     return;
00691   Coord.x = x;                                    // save new coordinates
00692   Coord.y = y;
00693     
00694   if(y/8 != Coord.page) {
00695       Coord.page = y/8;
00696     cmd = LCD_SET_PAGE | Coord.page;            // set y address on all chips    
00697     for(chip=0; chip < 2; chip++){
00698        WriteInstruction(cmd, chip);    
00699     }
00700   }
00701   chip = Coord.x/64;
00702   x = x % 64;
00703   cmd = LCD_SET_ADD | x;
00704   WriteInstruction(cmd, chip);                    // set x address on active chip        
00705 
00706 }
00707 
00708 
00709 /*****************************************************************************************/
00710 
00711 
00712 
00713 void KS0108::Putchar (int page, int col,unsigned char c) {
00714     if (c>31 && c<127){
00715     for(int i=0;i<5;i++){
00716         WriteDataColPag(page,col+i,System5x7[((c-32)*5+i)+6]);
00717      }
00718     }
00719 }
00720 
00721 
00722 
00723 void KS0108::PutString(unsigned int x, unsigned int y,char* str){
00724 
00725     while(*str != 0){
00726      Putchar(x,y,*str);
00727      str++;
00728      y+=System5x7[2];
00729     }
00730 
00731 }
00732 
00733 void KS0108::PrintFloat(float val, unsigned int x,unsigned int y){
00734    char buf[20] = {};  // prints up to 20 digits         
00735    sprintf(buf,"%f",val);
00736    PutString(x,y,buf);
00737 
00738 }
00739 
00740 
00741 void KS0108::PrintInteger(int val,unsigned int x,unsigned int y){
00742    char buf[20] = {};  // prints up to 20 digits         
00743    sprintf(buf,"%d",val);
00744    PutString(x,y,buf);
00745 }
00746 
00747 void KS0108::SelectFont(unsigned int* font,unsigned int color, FontCallback callback) {
00748     Font = font;
00749     FontRead = callback;
00750     FontColor = color;
00751 }
00752 
00753 
00754 int KS0108::PrintChar(char c) {
00755     unsigned int width = 0;
00756     unsigned int height = FontRead(Font+FONT_HEIGHT);
00757     unsigned int bytes = (height+7)/8;
00758     
00759     unsigned int firstChar = FontRead(Font+FONT_FIRST_CHAR);
00760     unsigned int charCount = FontRead(Font+FONT_CHAR_COUNT);
00761         
00762     unsigned int index = 0;
00763     unsigned int x=Coord.x , y=Coord.y;
00764 
00765     if(c < firstChar || c >= (firstChar+charCount)) {
00766         return 1;
00767     }
00768     c-= firstChar;
00769 
00770     if( FontRead(Font+FONT_LENGTH) == 0 && FontRead(Font+FONT_LENGTH+1) == 0) {
00771     // zero length is flag indicating fixed width font (array does not contain width data entries)
00772        width = FontRead(Font+FONT_FIXED_WIDTH); 
00773        index = c*bytes*width+FONT_WIDTH_TABLE;
00774     }
00775     else{
00776     // variable width font, read width data, to get the index
00777        for(unsigned int i=0; i<c; i++) {  
00778          index += FontRead(Font+FONT_WIDTH_TABLE+i);
00779        }
00780        index = index*bytes+charCount+FONT_WIDTH_TABLE;
00781        width = FontRead(Font+FONT_WIDTH_TABLE+c);
00782     }
00783 
00784     // last but not least, draw the character
00785     for(unsigned int i=0; i<bytes; i++) {
00786         unsigned int page = i*width;
00787         for(unsigned int j=0; j<width; j++) {
00788             unsigned int data = FontRead(Font+index+page+j);
00789         
00790             if(height > 8 && height < (i+1)*8) {
00791                 data >>= (i+1)*8-height;
00792             }
00793             
00794             WriteData(data);
00795 
00796         }
00797         // 1px gap between chars
00798         WriteData(0x00);
00799         GotoXY(x,Coord.y+8);
00800     
00801     }
00802     GotoXY(x+width+1, y);
00803     
00804 
00805     return 0;
00806 }
00807 
00808 void KS0108::PrintString(char* str) {
00809     int x = Coord.x;
00810     while(*str != 0) {
00811         if(*str == '\n') {
00812             GotoXY(x, Coord.y+ FontRead(Font+FONT_HEIGHT));
00813         } else {
00814             PrintChar(*str);
00815         }
00816         str++;
00817     }
00818 }
00819 
00820 void KS0108::PrintNumber(long n){
00821    char buf[10];  // prints up to 10 digits  
00822    char i=0;
00823    if(n==0)
00824        PrintChar('0');
00825    else{
00826      if(n < 0){
00827         PrintChar('-');
00828         n = -n;
00829      }
00830      while(n>0 && i <= 10){
00831        buf[i++] = n % 10;  // n % base
00832        n /= 10;   // n/= base
00833      }
00834      for(; i >0; i--)
00835          PrintChar((char) (buf[i-1] < 10 ? '0' + buf[i-1] : 'A' + buf[i-1] - 10));      
00836    }
00837 }
00838 
00839 
00840 
00841             
00842 
00843