Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of 4DGL-uLCD-SE by
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
Generated on Fri Jul 15 2022 01:44:25 by
