Extended library to include a screensaver

Dependencies:   SDFileSystem

Fork of 4DGL-uLCD-SE by Jay Danner

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers uLCD_4DGL_main.cpp Source File

uLCD_4DGL_main.cpp

00001 //
00002 // uLCD_4DGL is a class to drive 4D Systems uLCD 144 G2
00003 //
00004 // Copyright (C) <2010> Stephane ROCHON <stephane.rochon at free.fr>
00005 // Modifed for Goldelox processor <2013> Jim Hamblen
00006 //
00007 // uLCD_4DGL is free software: you can redistribute it and/or modify
00008 // it under the terms of the GNU General Public License as published by
00009 // the Free Software Foundation, either version 3 of the License, or
00010 // (at your option) any later version.
00011 //
00012 // uLCD_4DGL is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU General Public License for more details.
00016 //
00017 // You should have received a copy of the GNU General Public License
00018 // along with uLCD_4DGL.  If not, see <http://www.gnu.org/licenses/>.
00019 
00020 #include "mbed.h"
00021 #include "uLCD_4DGL.h"
00022 #define ARRAY_SIZE(X) sizeof(X)/sizeof(X[0])
00023 
00024 
00025 //******************************************************************************************************
00026 uLCD_4DGL :: uLCD_4DGL(PinName tx, PinName rx, PinName rst) 
00027     : sd(p5, p6, p7, p8, "sd")
00028     ,_cmd(tx, rx)
00029     ,_rst(rst)
00030     ,pc(USBTX, USBRX)
00031 {
00032     // Constructor
00033     _cmd.baud(9600);
00034 #if DEBUGMODE
00035     pc.baud(115200);
00036 
00037     pc.printf("\n\n\n");
00038     pc.printf("*********************\n");
00039     pc.printf("uLCD_4DGL CONSTRUCTOR\n");
00040     pc.printf("*********************\n");
00041 #endif
00042 
00043     _rst = 1;    // put RESET pin to high to start TFT screen
00044     reset();
00045     cls();       // clear screen
00046     current_col         = 0;            // initial cursor col
00047     current_row         = 0;            // initial cursor row
00048     current_color       = WHITE;        // initial text color
00049     current_orientation = IS_PORTRAIT;  // initial screen orientation
00050     current_hf = 1;
00051     current_wf = 1;
00052     set_font(FONT_7X8);                 // initial font
00053     set_time(1256729737);               // set manual time base to work from
00054     time(&lastDisplayActivityTime);     // initialize times for screensaver
00055     time(&now);                         // initialize times for screensaver
00056     time(&lastScreensaverInit);         // initialize times for screensaver
00057     max_active_screen_interval = 5;     // initial amount of seconds to wait before showing screensaver
00058     inScreensaverMode = false;          // initialize without screensaver
00059     inScreensaverHysteresis = false;    // initialize without screensaver
00060 //   text_mode(OPAQUE);                  // initial text mode
00061 }
00062 
00063 //******************************************************************************************************
00064 void uLCD_4DGL :: writeBYTE(char c)   // send a BYTE command to screen
00065 {
00066     time(&lastDisplayActivityTime); // update time to indicate that the screen is still active
00067     _cmd.putc(c);
00068     wait_us(500);  //mbed is too fast for LCD at high baud rates in some long commands
00069 
00070 #if DEBUGMODE
00071     pc.printf("   Char sent : 0x%02X\n",c);
00072 #endif
00073 
00074 }
00075 
00076 //******************************************************************************************************
00077 void uLCD_4DGL :: writeBYTEfast(char c)   // send a BYTE command to screen
00078 {
00079     time(&lastDisplayActivityTime); // update time to indicate that the screen is still active
00080     _cmd.putc(c);
00081     //wait_ms(0.0);  //mbed is too fast for LCD at high baud rates - but not in short commands
00082 
00083 #if DEBUGMODE
00084     pc.printf("   Char sent : 0x%02X\n",c);
00085 #endif
00086 
00087 }
00088 //******************************************************************************************************
00089 void uLCD_4DGL :: freeBUFFER(void)         // Clear serial buffer before writing command
00090 {
00091 
00092     while (_cmd.readable()) _cmd.getc();  // clear buffer garbage
00093 }
00094 
00095 //******************************************************************************************************
00096 int uLCD_4DGL :: writeCOMMAND(char *command, int number)   // send several BYTES making a command and return an answer
00097 {
00098 
00099 #if DEBUGMODE
00100     pc.printf("\n");
00101     pc.printf("New COMMAND : 0x%02X\n", command[0]);
00102 #endif
00103     time(&lastDisplayActivityTime); // update time to indicate that the screen is still active
00104     int i, resp = 0;
00105     freeBUFFER();
00106     writeBYTE(0xFF);
00107     for (i = 0; i < number; i++) {
00108         if (i<16)
00109             writeBYTEfast(command[i]); // send command to serial port
00110         else
00111             writeBYTE(command[i]); // send command to serial port but slower
00112     }
00113     while (!_cmd.readable()) wait_ms(TEMPO);              // wait for screen answer
00114     if (_cmd.readable()) resp = _cmd.getc();           // read response if any
00115     switch (resp) {
00116         case ACK :                                     // if OK return   1
00117             resp =  1;
00118             break;
00119         case NAK :                                     // if NOK return -1
00120             resp = -1;
00121             break;
00122         default :
00123             resp =  0;                                 // else return   0
00124             break;
00125     }
00126 #if DEBUGMODE
00127     pc.printf("   Answer received : %d\n",resp);
00128 #endif
00129 
00130     return resp;
00131 }
00132 
00133 //**************************************************************************
00134 void uLCD_4DGL :: reset()    // Reset Screen
00135 {
00136     time(&lastDisplayActivityTime); // update time to indicate that the screen is still active
00137     wait_ms(5);
00138     _rst = 0;               // put RESET pin to low
00139     wait_ms(5);         // wait a few milliseconds for command reception
00140     _rst = 1;               // put RESET back to high
00141     wait(3);                // wait 3s for screen to restart
00142 
00143     freeBUFFER();           // clean buffer from possible garbage
00144 }
00145 //******************************************************************************************************
00146 int uLCD_4DGL :: writeCOMMANDnull(char *command, int number)   // send several BYTES making a command and return an answer
00147 {
00148 
00149 #if DEBUGMODE
00150     pc.printf("\n");
00151     pc.printf("New COMMAND : 0x%02X\n", command[0]);
00152 #endif
00153     int i, resp = 0;
00154     freeBUFFER();
00155     writeBYTE(0x00); //command has a null prefix byte
00156     for (i = 0; i < number; i++) {
00157         if (i<16) //don't overflow LCD UART buffer
00158             writeBYTEfast(command[i]); // send command to serial port
00159         else
00160             writeBYTE(command[i]); // send command to serial port with delay
00161     }
00162     while (!_cmd.readable()) wait_ms(TEMPO);              // wait for screen answer
00163     if (_cmd.readable()) resp = _cmd.getc();           // read response if any
00164     switch (resp) {
00165         case ACK :                                     // if OK return   1
00166             resp =  1;
00167             break;
00168         case NAK :                                     // if NOK return -1
00169             resp = -1;
00170             break;
00171         default :
00172             resp =  0;                                 // else return   0
00173             break;
00174     }
00175 #if DEBUGMODE
00176     pc.printf("   Answer received : %d\n",resp);
00177 #endif
00178 
00179     return resp;
00180 }
00181 
00182 //**************************************************************************
00183 void uLCD_4DGL :: cls()    // clear screen
00184 {
00185     char command[1] = "";
00186 
00187     command[0] = CLS;
00188     writeCOMMAND(command, 1);
00189     current_row=0;
00190     current_col=0;
00191     current_hf = 1;
00192     current_wf = 1;
00193     set_font(FONT_7X8);                 // initial font
00194 }
00195 
00196 //**************************************************************************
00197 int uLCD_4DGL :: version()    // get API version
00198 {
00199     char command[2] = "";
00200     command[0] = '\x00';
00201     command[1] = VERSION;
00202     return readVERSION(command, 2);
00203 }
00204 
00205 //**************************************************************************
00206 void uLCD_4DGL :: baudrate(int speed)    // set screen baud rate
00207 {
00208     char command[3]= "";
00209     writeBYTE(0x00);
00210     command[0] = BAUDRATE;
00211     command[1] = 0;
00212     int newbaud = BAUD_9600;
00213     switch (speed) {
00214         case  110 :
00215             newbaud = BAUD_110;
00216             break;
00217         case  300 :
00218             newbaud = BAUD_300;
00219             break;
00220         case  600 :
00221             newbaud = BAUD_600;
00222             break;
00223         case 1200 :
00224             newbaud = BAUD_1200;
00225             break;
00226         case 2400 :
00227             newbaud = BAUD_2400;
00228             break;
00229         case 4800 :
00230             newbaud = BAUD_4800;
00231             break;
00232         case 9600 :
00233             newbaud = BAUD_9600;
00234             break;
00235         case 14400 :
00236             newbaud = BAUD_14400;
00237             break;
00238         case 19200 :
00239             newbaud = BAUD_19200;
00240             break;
00241         case 31250 :
00242             newbaud = BAUD_31250;
00243             break;
00244         case 38400 :
00245             newbaud = BAUD_38400;
00246             break;
00247         case 56000 :
00248             newbaud = BAUD_56000;
00249             break;
00250         case 57600 :
00251             newbaud = BAUD_57600;
00252             break;
00253         case 115200 :
00254             newbaud = BAUD_115200;
00255             break;
00256         case 128000 :
00257             newbaud = BAUD_128000;
00258             break;
00259         case 256000 :
00260             newbaud = BAUD_256000;
00261             break;
00262         case 300000 :
00263             newbaud = BAUD_300000;
00264             speed = 272727;
00265             break;
00266         case 375000 :
00267             newbaud = BAUD_375000;
00268             speed = 333333;
00269             break;
00270         case 500000 :
00271             newbaud = BAUD_500000;
00272             speed = 428571;
00273             break;
00274         case 600000 :
00275             newbaud = BAUD_600000;
00276             break;
00277         case 750000 : //rates over 600000 are not documented, but seem to work
00278             newbaud = BAUD_750000;
00279             break;
00280         case 1000000 :  
00281             newbaud = BAUD_1000000;
00282             break;
00283         case 1500000 :
00284             newbaud = BAUD_1500000;
00285             break;
00286         case 3000000 :
00287             newbaud = BAUD_3000000;
00288             break;
00289         default   :
00290             newbaud = BAUD_9600;
00291             speed = 9600;
00292             break;
00293     }
00294 
00295     int i, resp = 0;
00296 
00297     freeBUFFER();
00298     command[1] = char(newbaud >>8);
00299     command[2] = char(newbaud % 256);
00300     wait_ms(1);
00301     for (i = 0; i <3; i++) writeBYTEfast(command[i]);      // send command to serial port
00302     for (i = 0; i<10; i++) wait_ms(1); 
00303     //dont change baud until all characters get sent out
00304     _cmd.baud(speed);                                  // set mbed to same speed
00305     i=0;
00306     while ((!_cmd.readable()) && (i<25000)) {
00307         wait_ms(TEMPO);           // wait for screen answer - comes 100ms after change
00308         i++; //timeout if ack character missed by baud change
00309     }
00310     if (_cmd.readable()) resp = _cmd.getc();           // read response if any
00311     switch (resp) {
00312         case ACK :                                     // if OK return   1
00313             resp =  1;
00314             break;
00315         case NAK :                                     // if NOK return -1
00316             resp = -1;
00317             break;
00318         default :
00319             resp =  0;                                 // else return   0
00320             break;
00321     }
00322 }
00323 
00324 //******************************************************************************************************
00325 int uLCD_4DGL :: readVERSION(char *command, int number)   // read screen info and populate data
00326 {
00327     int i, temp = 0, resp = 0;
00328     char response[5] = "";
00329 
00330     freeBUFFER();
00331 
00332     for (i = 0; i < number; i++) writeBYTE(command[i]);    // send all chars to serial port
00333 
00334     while (!_cmd.readable()) wait_ms(TEMPO);               // wait for screen answer
00335 
00336     while (_cmd.readable() && resp < ARRAY_SIZE(response)) {
00337         temp = _cmd.getc();
00338         response[resp++] = (char)temp;
00339     }
00340     switch (resp) {
00341         case 2 :                                           // if OK populate data and return 1
00342             revision  = response[0]<<8 + response[1];
00343             resp      = 1;
00344             break;
00345         default :
00346             resp =  0;                                     // else return 0
00347             break;
00348     }
00349     time(&lastDisplayActivityTime); // update time to indicate that the screen is still active
00350     return resp;
00351 }
00352 
00353 //****************************************************************************************************
00354 void uLCD_4DGL :: background_color(int color)              // set screen background color
00355 {
00356     char command[3]= "";                                  // input color is in 24bits like 0xRRGGBB
00357 
00358     command[0] = BCKGDCOLOR;
00359 
00360     int red5   = (color >> (16 + 3)) & 0x1F;              // get red on 5 bits
00361     int green6 = (color >> (8 + 2))  & 0x3F;              // get green on 6 bits
00362     int blue5  = (color >> (0 + 3))  & 0x1F;              // get blue on 5 bits
00363 
00364     command[1] = ((red5 << 3)   + (green6 >> 3)) & 0xFF;  // first part of 16 bits color
00365     command[2] = ((green6 << 5) + (blue5 >>  0)) & 0xFF;  // second part of 16 bits color
00366 
00367     writeCOMMAND(command, 3);
00368 }
00369 
00370 //****************************************************************************************************
00371 void uLCD_4DGL :: textbackground_color(int color)              // set screen background color
00372 {
00373     char command[3]= "";                                  // input color is in 24bits like 0xRRGGBB
00374 
00375     command[0] = TXTBCKGDCOLOR;
00376 
00377     int red5   = (color >> (16 + 3)) & 0x1F;              // get red on 5 bits
00378     int green6 = (color >> (8 + 2))  & 0x3F;              // get green on 6 bits
00379     int blue5  = (color >> (0 + 3))  & 0x1F;              // get blue on 5 bits
00380 
00381     command[1] = ((red5 << 3)   + (green6 >> 3)) & 0xFF;  // first part of 16 bits color
00382     command[2] = ((green6 << 5) + (blue5 >>  0)) & 0xFF;  // second part of 16 bits color
00383 
00384     writeCOMMAND(command, 3);
00385 }
00386 
00387 //****************************************************************************************************
00388 void uLCD_4DGL :: display_control(char mode)     // set screen mode to value
00389 {
00390     char command[3]= "";
00391 
00392     command[0] = DISPCONTROL;
00393     command[1] = 0;
00394     command[2] = mode;
00395 
00396     if (mode ==  ORIENTATION) {
00397         switch (mode) {
00398             case LANDSCAPE :
00399                 current_orientation = IS_LANDSCAPE;
00400                 break;
00401             case LANDSCAPE_R :
00402                 current_orientation = IS_LANDSCAPE;
00403                 break;
00404             case PORTRAIT :
00405                 current_orientation = IS_PORTRAIT;
00406                 break;
00407             case PORTRAIT_R :
00408                 current_orientation = IS_PORTRAIT;
00409                 break;
00410         }
00411     }
00412     writeCOMMAND(command, 3);
00413     set_font(current_font);
00414 }
00415 //****************************************************************************************************
00416 void uLCD_4DGL :: display_power(char mode)     // set screen mode to value
00417 {
00418     char command[3]= "";
00419 
00420     command[0] = DISPPOWER;
00421     command[1] = 0;
00422     command[2] = mode;
00423     writeCOMMAND(command, 3);
00424     time(&lastDisplayActivityTime); // update time to indicate that the screen is still active
00425 }
00426 //****************************************************************************************************
00427 void uLCD_4DGL :: set_volume(char value)     // set sound volume to value
00428 {
00429     char command[2]= "";
00430 
00431     command[0] = SETVOLUME;
00432     command[1] = value;
00433 
00434     writeCOMMAND(command, 2);
00435 }
00436 
00437 
00438 //******************************************************************************************************
00439 int uLCD_4DGL :: getSTATUS(char *command, int number)   // read screen info and populate data
00440 {
00441 
00442 #if DEBUGMODE
00443     pc.printf("\n");
00444     pc.printf("New COMMAND : 0x%02X\n", command[0]);
00445 #endif
00446 
00447     int i, temp = 0, resp = 0;
00448     char response[5] = "";
00449 
00450     freeBUFFER();
00451 
00452     for (i = 0; i < number; i++) writeBYTE(command[i]);    // send all chars to serial port
00453 
00454     while (!_cmd.readable()) wait_ms(TEMPO);    // wait for screen answer
00455 
00456     while (_cmd.readable() && resp < ARRAY_SIZE(response)) {
00457         temp = _cmd.getc();
00458         response[resp++] = (char)temp;
00459     }
00460     switch (resp) {
00461         case 4 :
00462             resp = (int)response[1];         // if OK populate data
00463             break;
00464         default :
00465             resp =  -1;                      // else return   0
00466             break;
00467     }
00468 
00469 #if DEBUGMODE
00470     pc.printf("   Answer received : %d\n", resp);
00471 #endif
00472 
00473     return resp;
00474 }
00475