Fixed a few minor issues in 4DGL library Moved pc serial port object used for debug output into 4DGL object itself. Previously it was a global object but its constructor wasn't getting run before the global constructor for the 4DGL object itself which led to an assert in the serial code. I also fixed a few potential buffer overruns that I saw in the code as well.

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers TFT_4DGL_main.cpp Source File

TFT_4DGL_main.cpp

00001 //
00002 // TFT_4DGL is a class to drive 4D Systems TFT touch screens
00003 //
00004 // Copyright (C) <2010> Stephane ROCHON <stephane.rochon at free.fr>
00005 //
00006 // TFT_4DGL is free software: you can redistribute it and/or modify
00007 // it under the terms of the GNU General Public License as published by
00008 // the Free Software Foundation, either version 3 of the License, or
00009 // (at your option) any later version.
00010 //
00011 // TFT_4DGL is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU General Public License
00017 // along with TFT_4DGL.  If not, see <http://www.gnu.org/licenses/>.
00018 
00019 #include "mbed.h"
00020 #include "TFT_4DGL.h"
00021 
00022 #define ARRAY_SIZE(X) sizeof(X)/sizeof(X[0])
00023 
00024 //Serial pc(USBTX,USBRX);
00025 
00026 //******************************************************************************************************
00027 TFT_4DGL :: TFT_4DGL(PinName tx, PinName rx, PinName rst) : _cmd(tx, rx), 
00028                                                             _rst(rst) 
00029 #if DEBUGMODE
00030                                                             ,pc(USBTX, USBRX)
00031 #endif // DEBUGMODE
00032 { // Constructor
00033 
00034 #if DEBUGMODE
00035     pc.baud(115200);
00036 
00037     pc.printf("\n\n\n");
00038     pc.printf("********************\n");
00039     pc.printf("TFT_4DGL CONSTRUCTOR\n");
00040     pc.printf("********************\n");
00041 #endif
00042 
00043     _rst = 1;    // put RESET pin to high to start TFT screen
00044 
00045     reset();
00046     autobaud();  // send autobaud command
00047     version();   // get version information
00048     cls();       // clear screen
00049 
00050     current_col         = 0;            // initial cursor col
00051     current_row         = 0;            // initial cursor row
00052     current_color       = WHITE;        // initial text color
00053     current_orientation = IS_PORTRAIT;  // initial screen orientation
00054 
00055     set_font(FONT_5X7);                 // initial font
00056     text_mode(OPAQUE);                  // initial texr mode
00057 }
00058 
00059 //******************************************************************************************************
00060 void TFT_4DGL :: writeBYTE(char c) { // send a BYTE command to screen
00061 
00062     _cmd.putc(c);
00063     wait_ms(1);
00064 
00065 #if DEBUGMODE
00066     pc.printf("   Char sent : 0x%02X\n",c);
00067 #endif
00068 
00069 }
00070 
00071 //******************************************************************************************************
00072 void TFT_4DGL :: freeBUFFER(void) {       // Clear serial buffer before writing command
00073 
00074     while (_cmd.readable()) _cmd.getc();  // clear buffer garbage
00075 }
00076 
00077 //******************************************************************************************************
00078 int TFT_4DGL :: writeCOMMAND(char *command, int number) { // send several BYTES making a command and return an answer
00079 
00080 #if DEBUGMODE
00081     pc.printf("\n");
00082     pc.printf("New COMMAND : 0x%02X\n", command[0]);
00083 #endif
00084     int i, resp = 0;
00085     freeBUFFER();
00086 
00087     for (i = 0; i < number; i++) writeBYTE(command[i]); // send command to serial port
00088 
00089     while (!_cmd.readable()) wait_ms(TEMPO);              // wait for screen answer
00090     if (_cmd.readable()) resp = _cmd.getc();           // read response if any
00091     switch (resp) {
00092         case ACK :                                     // if OK return   1
00093             resp =  1;
00094             break;
00095         case NAK :                                     // if NOK return -1
00096             resp = -1;
00097             break;
00098         default :
00099             resp =  0;                                 // else return   0
00100             break;
00101     }
00102 #if DEBUGMODE
00103     pc.printf("   Answer received : %d\n",resp);
00104 #endif
00105 
00106     return resp;
00107 }
00108 
00109 //**************************************************************************
00110 void TFT_4DGL :: reset() {  // Reset Screen
00111 
00112     _rst = 0;               // put RESET pin to low
00113     wait_ms(TEMPO);         // wait a few milliseconds for command reception
00114     _rst = 1;               // put RESET back to high
00115     wait(3);                // wait 3s for screen to restart
00116 
00117     freeBUFFER();           // clean buffer from possible garbage
00118 }
00119 
00120 //**************************************************************************
00121 void TFT_4DGL :: autobaud() { // send AutoBaud command (9600)
00122     char command[1] = "";
00123     command[0] = AUTOBAUD;
00124     writeCOMMAND(command, 1);
00125 }
00126 
00127 //**************************************************************************
00128 void TFT_4DGL :: cls() {  // clear screen
00129     char command[1] = "";
00130     command[0] = CLS;
00131     writeCOMMAND(command, 1);
00132 }
00133 
00134 //**************************************************************************
00135 void TFT_4DGL :: version() {  // get API version
00136     char command[2] = "";
00137     command[0] = VERSION;
00138     command[1] = OFF;
00139     readVERSION(command, 2);
00140 }
00141 
00142 //**************************************************************************
00143 void TFT_4DGL :: baudrate(int speed) {  // set screen baud rate
00144     char command[2]= "";
00145     command[0] = BAUDRATE;
00146     switch (speed) {
00147         case  110 :
00148             command[1] = BAUD_110;
00149             break;
00150         case  300 :
00151             command[1] = BAUD_300;
00152             break;
00153         case  600 :
00154             command[1] = BAUD_600;
00155             break;
00156         case 1200 :
00157             command[1] = BAUD_1200;
00158             break;
00159         case 2400 :
00160             command[1] = BAUD_2400;
00161             break;
00162         case 4800 :
00163             command[1] = BAUD_4800;
00164             break;
00165         case 9600 :
00166             command[1] = BAUD_9600;
00167             break;
00168         case 14400 :
00169             command[1] = BAUD_14400;
00170             break;
00171         case 19200 :
00172             command[1] = BAUD_19200;
00173             break;
00174         case 31250 :
00175             command[1] = BAUD_31250;
00176             break;
00177         case 38400 :
00178             command[1] = BAUD_38400;
00179             break;
00180         case 56000 :
00181             command[1] = BAUD_56000;
00182             break;
00183         case 57600 :
00184             command[1] = BAUD_57600;
00185             break;
00186         case 115200 :
00187             command[1] = BAUD_115200;
00188             break;
00189         case 128000 :
00190             command[1] = BAUD_128000;
00191             break;
00192         case 256000 :
00193             command[1] = BAUD_256000;
00194             break;
00195         default   :
00196             command[1] = BAUD_9600;
00197             speed = 9600;
00198             break;
00199     }
00200 
00201     int i, resp = 0;
00202 
00203     freeBUFFER();
00204 
00205     for (i = 0; i <2; i++) writeBYTE(command[i]);      // send command to serial port
00206     _cmd.baud(speed);                                  // set mbed to same speed
00207 
00208     while (!_cmd.readable()) wait_ms(TEMPO);           // wait for screen answer
00209 
00210     if (_cmd.readable()) resp = _cmd.getc();           // read response if any
00211     switch (resp) {
00212         case ACK :                                     // if OK return   1
00213             resp =  1;
00214             break;
00215         case NAK :                                     // if NOK return -1
00216             resp = -1;
00217             break;
00218         default :
00219             resp =  0;                                 // else return   0
00220             break;
00221     }
00222 }
00223 
00224 //******************************************************************************************************
00225 int TFT_4DGL :: readVERSION(char *command, int number) { // read screen info and populate data
00226 
00227     int i, temp = 0, resp = 0;
00228     char response[5] = "";
00229 
00230     freeBUFFER();
00231 
00232     for (i = 0; i < number; i++) writeBYTE(command[i]);    // send all chars to serial port
00233 
00234     while (!_cmd.readable()) wait_ms(TEMPO);               // wait for screen answer
00235 
00236     while (_cmd.readable() && resp < ARRAY_SIZE(response)) {
00237         temp = _cmd.getc();
00238         response[resp++] = (char)temp;
00239     }
00240     switch (resp) {
00241         case 5 :                                           // if OK populate data and return 1
00242             type      = response[0];
00243             revision  = response[1];
00244             firmware  = response[2];
00245             reserved1 = response[3];
00246             reserved2 = response[4];
00247             resp      = 1;
00248             break;
00249         default :
00250             resp =  0;                                     // else return 0
00251             break;
00252     }
00253     return resp;
00254 }
00255 
00256 //****************************************************************************************************
00257 void TFT_4DGL :: background_color(int color) {            // set screen background color
00258     char command[3]= "";                                  // input color is in 24bits like 0xRRGGBB
00259 
00260     command[0] = BCKGDCOLOR;
00261 
00262     int red5   = (color >> (16 + 3)) & 0x1F;              // get red on 5 bits
00263     int green6 = (color >> (8 + 2))  & 0x3F;              // get green on 6 bits
00264     int blue5  = (color >> (0 + 3))  & 0x1F;              // get blue on 5 bits
00265 
00266     command[1] = ((red5 << 3)   + (green6 >> 3)) & 0xFF;  // first part of 16 bits color
00267     command[2] = ((green6 << 5) + (blue5 >>  0)) & 0xFF;  // second part of 16 bits color
00268 
00269     writeCOMMAND(command, 3);
00270 }
00271 
00272 //****************************************************************************************************
00273 void TFT_4DGL :: display_control(char mode, char value) {   // set screen mode to value
00274     char command[3]= "";
00275 
00276     command[0] = DISPCONTROL;
00277     command[1] = mode;
00278     command[2] = value;
00279 
00280     if (mode ==  ORIENTATION) {
00281         switch (value) {
00282             case LANDSCAPE :
00283                 current_orientation = IS_LANDSCAPE;
00284                 break;
00285             case LANDSCAPE_R :
00286                 current_orientation = IS_LANDSCAPE;
00287                 break;
00288             case PORTRAIT :
00289                 current_orientation = IS_PORTRAIT;
00290                 break;
00291             case PORTRAIT_R :
00292                 current_orientation = IS_PORTRAIT;
00293                 break;
00294         }
00295     }
00296     writeCOMMAND(command, 3);
00297     set_font(current_font);
00298 }
00299 
00300 //****************************************************************************************************
00301 void TFT_4DGL :: set_volume(char value) {   // set sound volume to value
00302     char command[2]= "";
00303 
00304     command[0] = SETVOLUME;
00305     command[1] = value;
00306 
00307     writeCOMMAND(command, 2);
00308 }
00309 
00310 
00311 //******************************************************************************************************
00312 void TFT_4DGL :: getTOUCH(char *command, int number, int *x, int *y) { // read screen info and populate data
00313 
00314 #if DEBUGMODE
00315     pc.printf("\n");
00316     pc.printf("New COMMAND : 0x%02X\n", command[0]);
00317 #endif
00318     int i, temp = 0, resp = 0;
00319     char response[5] = "";
00320 
00321     freeBUFFER();
00322 
00323     for (i = 0; i < number; i++) writeBYTE(command[i]);    // send all chars to serial port
00324 
00325     while (!_cmd.readable()) wait_ms(TEMPO);               // wait for screen answer
00326 
00327     while (_cmd.readable() && resp < ARRAY_SIZE(response)) {
00328         temp = _cmd.getc();
00329         response[resp++] = (char)temp;
00330     }
00331 
00332 #if DEBUGMODE
00333     pc.printf("   Answer received %d : 0x%02X 0x%02X 0x%02X 0x%02X\n", resp, response[0], response[1], response[2], response[3]);
00334 #endif
00335 
00336     switch (resp) {
00337         case 4 :                                                              // if OK populate data
00338             *x = ((response[0]<<8)+ response[1]) * (response[0] != 0xFF);
00339             *y = ((response[2]<<8)+ response[3]) * (response[2] != 0xFF);
00340             break;
00341         default :
00342             *x = -1;
00343             *y = -1;
00344             break;
00345     }
00346 
00347 #if DEBUGMODE
00348     pc.printf("   X,Y : %03d,%03d\n", *x, *y);
00349 #endif
00350 }
00351 
00352 //******************************************************************************************************
00353 int TFT_4DGL :: getSTATUS(char *command, int number) { // read screen info and populate data
00354 
00355 #if DEBUGMODE
00356     pc.printf("\n");
00357     pc.printf("New COMMAND : 0x%02X\n", command[0]);
00358 #endif
00359 
00360     int i, temp = 0, resp = 0;
00361     char response[5] = "";
00362 
00363     freeBUFFER();
00364 
00365     for (i = 0; i < number; i++) writeBYTE(command[i]);    // send all chars to serial port
00366 
00367     while (!_cmd.readable()) wait_ms(TEMPO);    // wait for screen answer
00368 
00369     while (_cmd.readable() && resp < ARRAY_SIZE(response)) {
00370         temp = _cmd.getc();
00371         response[resp++] = (char)temp;
00372     }
00373     switch (resp) {
00374         case 4 :
00375             resp = (int)response[1];         // if OK populate data
00376             break;
00377         default :
00378             resp =  -1;                      // else return   0
00379             break;
00380     }
00381     
00382 #if DEBUGMODE
00383     pc.printf("   Answer received : %d\n", resp);
00384 #endif
00385 
00386     return resp;
00387 }