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
- Committer:
- 4180_1
- Date:
- 2013-11-25
- Revision:
- 6:b759b69cbaf9
- Parent:
- 5:8936798c19a3
- Child:
- 7:e39a44de229a
File content as of revision 6:b759b69cbaf9:
//
// uLCD_4DGL is a class to drive 4D Systems uLCD 144 G2
//
// Copyright (C) <2010> Stephane ROCHON <stephane.rochon at free.fr>
//
// uLCD_4DGL is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// uLCD_4DGL is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with uLCD_4DGL.  If not, see <http://www.gnu.org/licenses/>.
#include "mbed.h"
#include "uLCD_4DGL.h"
#define ARRAY_SIZE(X) sizeof(X)/sizeof(X[0])
//Serial pc(USBTX,USBRX);
//******************************************************************************************************
uLCD_4DGL :: uLCD_4DGL(PinName tx, PinName rx, PinName rst) : _cmd(tx, rx),
    _rst(rst)
#if DEBUGMODE
    ,pc(USBTX, USBRX)
#endif // DEBUGMODE
{
    // Constructor
    _cmd.baud(9600);
#if DEBUGMODE
    pc.baud(115200);
    pc.printf("\n\n\n");
    pc.printf("*********************\n");
    pc.printf("uLCD_4DGL CONSTRUCTOR\n");
    pc.printf("*********************\n");
#endif
    _rst = 1;    // put RESET pin to high to start TFT screen
    reset();
//  autobaud();  // send autobaud command
//   version();   // get version information
    cls();       // clear screen
    current_col         = 0;            // initial cursor col
    current_row         = 0;            // initial cursor row
    current_color       = WHITE;        // initial text color
    current_orientation = IS_PORTRAIT;  // initial screen orientation
    current_hf = 1;
    current_wf = 1;
    set_font(FONT_7X8);                 // initial font
//   text_mode(OPAQUE);                  // initial texr mode
}
//******************************************************************************************************
void uLCD_4DGL :: writeBYTE(char c)   // send a BYTE command to screen
{
    _cmd.putc(c);
    wait_ms(1);  //mbed is too fast for LCD at high baud rates in long commands
#if DEBUGMODE
    pc.printf("   Char sent : 0x%02X\n",c);
#endif
}
//******************************************************************************************************
void uLCD_4DGL :: writeBYTEfast(char c)   // send a BYTE command to screen
{
    _cmd.putc(c);
    //wait_ms(0.0);  //mbed is too fast for LCD at high baud rates - but not in some commands
#if DEBUGMODE
    pc.printf("   Char sent : 0x%02X\n",c);
#endif
}
//******************************************************************************************************
void uLCD_4DGL :: freeBUFFER(void)         // Clear serial buffer before writing command
{
    while (_cmd.readable()) _cmd.getc();  // clear buffer garbage
}
//******************************************************************************************************
int uLCD_4DGL :: writeCOMMAND(char *command, int number)   // send several BYTES making a command and return an answer
{
#if DEBUGMODE
    pc.printf("\n");
    pc.printf("New COMMAND : 0x%02X\n", command[0]);
#endif
    int i, resp = 0;
    freeBUFFER();
    writeBYTE(0xFF);
    for (i = 0; i < number; i++) {
        if (i<16)
            writeBYTEfast(command[i]); // send command to serial port
        else
            writeBYTE(command[i]); // send command to serial port but slower
    }
    while (!_cmd.readable()) wait_ms(TEMPO);              // wait for screen answer
    if (_cmd.readable()) resp = _cmd.getc();           // read response if any
    switch (resp) {
        case ACK :                                     // if OK return   1
            resp =  1;
            break;
        case NAK :                                     // if NOK return -1
            resp = -1;
            break;
        default :
            resp =  0;                                 // else return   0
            break;
    }
#if DEBUGMODE
    pc.printf("   Answer received : %d\n",resp);
#endif
    return resp;
}
//**************************************************************************
void uLCD_4DGL :: reset()    // Reset Screen
{
    wait_ms(5);
    _rst = 0;               // put RESET pin to low
    wait_ms(5);         // wait a few milliseconds for command reception
    _rst = 1;               // put RESET back to high
    wait(3);                // wait 3s for screen to restart
    freeBUFFER();           // clean buffer from possible garbage
}
//******************************************************************************************************
int uLCD_4DGL :: writeCOMMANDnull(char *command, int number)   // send several BYTES making a command and return an answer
{
#if DEBUGMODE
    pc.printf("\n");
    pc.printf("New COMMAND : 0x%02X\n", command[0]);
#endif
    int i, resp = 0;
    freeBUFFER();
    writeBYTE(0x00); //command has a null prefix byte
    for (i = 0; i < number; i++) {
        if (i<16)
            writeBYTEfast(command[i]); // send command to serial port
        else
            writeBYTE(command[i]); // send command to serial port
    }
    while (!_cmd.readable()) wait_ms(TEMPO);              // wait for screen answer
    if (_cmd.readable()) resp = _cmd.getc();           // read response if any
    switch (resp) {
        case ACK :                                     // if OK return   1
            resp =  1;
            break;
        case NAK :                                     // if NOK return -1
            resp = -1;
            break;
        default :
            resp =  0;                                 // else return   0
            break;
    }
#if DEBUGMODE
    pc.printf("   Answer received : %d\n",resp);
#endif
    return resp;
}
//**************************************************************************
void uLCD_4DGL :: autobaud()   // send AutoBaud command (9600)
{
    writeBYTE(AUTOBAUD);
    char command[1] = "";
    command[0] = AUTOBAUD;
    writeCOMMAND(command, 1);
}
//**************************************************************************
void uLCD_4DGL :: cls()    // clear screen
{
    char command[1] = "";
    command[0] = CLS;
    writeCOMMAND(command, 1);
    current_hf = 1;
    current_wf = 1;
    set_font(FONT_7X8);                 // initial font
}
//**************************************************************************
void uLCD_4DGL :: version()    // get API version
{
    char command[2] = "";
    command[0] = VERSION;
    command[1] = OFF;
    readVERSION(command, 2);
}
//**************************************************************************
void uLCD_4DGL :: baudrate(int speed)    // set screen baud rate
{
    char command[3]= "";
    writeBYTE(0x00);
    command[0] = BAUDRATE;
    command[1] = 0;
    int newbaud = BAUD_9600;
    switch (speed) {
        case  110 :
            newbaud = BAUD_110;
            break;
        case  300 :
            newbaud = BAUD_300;
            break;
        case  600 :
            newbaud = BAUD_600;
            break;
        case 1200 :
            newbaud = BAUD_1200;
            break;
        case 2400 :
            newbaud = BAUD_2400;
            break;
        case 4800 :
            newbaud = BAUD_4800;
            break;
        case 9600 :
            newbaud = BAUD_9600;
            break;
        case 14400 :
            newbaud = BAUD_14400;
            break;
        case 19200 :
            newbaud = BAUD_19200;
            break;
        case 31250 :
            newbaud = BAUD_31250;
            break;
        case 38400 :
            newbaud = BAUD_38400;
            break;
        case 56000 :
            newbaud = BAUD_56000;
            break;
        case 57600 :
            newbaud = BAUD_57600;
            break;
        case 115200 :
            newbaud = BAUD_115200;
            break;
        case 128000 :
            newbaud = BAUD_128000;
            break;
        case 256000 :
            newbaud = BAUD_256000;
            break;
        case 300000 :
            newbaud = BAUD_300000;
            speed = 272727;
            break;
        case 375000 :
            newbaud = BAUD_375000;
            speed = 333333;
            break;
        case 500000 :
            newbaud = BAUD_500000;
            speed = 428571;
            break;
        case 600000 :
            newbaud = BAUD_600000;
            break;
        default   :
            newbaud = BAUD_9600;
            speed = 9600;
            break;
    }
    int i, resp = 0;
    freeBUFFER();
    command[1] = char(newbaud >>8);
    command[2] = char(newbaud % 256);
    wait_ms(1);
    for (i = 0; i <3; i++) writeBYTEfast(command[i]);      // send command to serial port
    wait_ms(10); //dont change baud until all characters get sent out
    _cmd.baud(speed);                                  // set mbed to same speed
    i=0;
    while ((!_cmd.readable()) && (i<25000)) {
        wait_ms(TEMPO);           // wait for screen answer - comes 100ms after change
        i++; //timeout if ack character missed by baud change
    }
    if (_cmd.readable()) resp = _cmd.getc();           // read response if any
    switch (resp) {
        case ACK :                                     // if OK return   1
            resp =  1;
            break;
        case NAK :                                     // if NOK return -1
            resp = -1;
            break;
        default :
            resp =  0;                                 // else return   0
            break;
    }
}
//******************************************************************************************************
int uLCD_4DGL :: readVERSION(char *command, int number)   // read screen info and populate data
{
    int i, temp = 0, resp = 0;
    char response[5] = "";
    freeBUFFER();
    for (i = 0; i < number; i++) writeBYTE(command[i]);    // send all chars to serial port
    while (!_cmd.readable()) wait_ms(TEMPO);               // wait for screen answer
    while (_cmd.readable() && resp < ARRAY_SIZE(response)) {
        temp = _cmd.getc();
        response[resp++] = (char)temp;
    }
    switch (resp) {
        case 2 :                                           // if OK populate data and return 1
            revision  = response[0]<<8 + response[1];
            resp      = 1;
            break;
        default :
            resp =  0;                                     // else return 0
            break;
    }
    return resp;
}
//****************************************************************************************************
void uLCD_4DGL :: background_color(int color)              // set screen background color
{
    char command[3]= "";                                  // input color is in 24bits like 0xRRGGBB
    command[0] = BCKGDCOLOR;
    int red5   = (color >> (16 + 3)) & 0x1F;              // get red on 5 bits
    int green6 = (color >> (8 + 2))  & 0x3F;              // get green on 6 bits
    int blue5  = (color >> (0 + 3))  & 0x1F;              // get blue on 5 bits
    command[1] = ((red5 << 3)   + (green6 >> 3)) & 0xFF;  // first part of 16 bits color
    command[2] = ((green6 << 5) + (blue5 >>  0)) & 0xFF;  // second part of 16 bits color
    writeCOMMAND(command, 3);
}
//****************************************************************************************************
void uLCD_4DGL :: textbackground_color(int color)              // set screen background color
{
    char command[3]= "";                                  // input color is in 24bits like 0xRRGGBB
    command[0] = TXTBCKGDCOLOR;
    int red5   = (color >> (16 + 3)) & 0x1F;              // get red on 5 bits
    int green6 = (color >> (8 + 2))  & 0x3F;              // get green on 6 bits
    int blue5  = (color >> (0 + 3))  & 0x1F;              // get blue on 5 bits
    command[1] = ((red5 << 3)   + (green6 >> 3)) & 0xFF;  // first part of 16 bits color
    command[2] = ((green6 << 5) + (blue5 >>  0)) & 0xFF;  // second part of 16 bits color
    writeCOMMAND(command, 3);
}
//****************************************************************************************************
void uLCD_4DGL :: display_control(char mode, char value)     // set screen mode to value
{
    char command[3]= "";
    command[0] = DISPCONTROL;
    command[1] = mode;
    command[2] = value;
    if (mode ==  ORIENTATION) {
        switch (value) {
            case LANDSCAPE :
                current_orientation = IS_LANDSCAPE;
                break;
            case LANDSCAPE_R :
                current_orientation = IS_LANDSCAPE;
                break;
            case PORTRAIT :
                current_orientation = IS_PORTRAIT;
                break;
            case PORTRAIT_R :
                current_orientation = IS_PORTRAIT;
                break;
        }
    }
    writeCOMMAND(command, 3);
    set_font(current_font);
}
//****************************************************************************************************
void uLCD_4DGL :: set_volume(char value)     // set sound volume to value
{
    char command[2]= "";
    command[0] = SETVOLUME;
    command[1] = value;
    writeCOMMAND(command, 2);
}
//******************************************************************************************************
void uLCD_4DGL :: getTOUCH(char *command, int number, int *x, int *y)   // read screen info and populate data
{
#if DEBUGMODE
    pc.printf("\n");
    pc.printf("New COMMAND : 0x%02X\n", command[0]);
#endif
    int i, temp = 0, resp = 0;
    char response[5] = "";
    freeBUFFER();
    for (i = 0; i < number; i++) writeBYTE(command[i]);    // send all chars to serial port
    while (!_cmd.readable()) wait_ms(TEMPO);               // wait for screen answer
    while (_cmd.readable() && resp < ARRAY_SIZE(response)) {
        temp = _cmd.getc();
        response[resp++] = (char)temp;
    }
#if DEBUGMODE
    pc.printf("   Answer received %d : 0x%02X 0x%02X 0x%02X 0x%02X\n", resp, response[0], response[1], response[2], response[3]);
#endif
    switch (resp) {
        case 4 :                                                              // if OK populate data
            *x = ((response[0]<<8)+ response[1]) * (response[0] != 0xFF);
            *y = ((response[2]<<8)+ response[3]) * (response[2] != 0xFF);
            break;
        default :
            *x = -1;
            *y = -1;
            break;
    }
#if DEBUGMODE
    pc.printf("   X,Y : %03d,%03d\n", *x, *y);
#endif
}
//******************************************************************************************************
int uLCD_4DGL :: getSTATUS(char *command, int number)   // read screen info and populate data
{
#if DEBUGMODE
    pc.printf("\n");
    pc.printf("New COMMAND : 0x%02X\n", command[0]);
#endif
    int i, temp = 0, resp = 0;
    char response[5] = "";
    freeBUFFER();
    for (i = 0; i < number; i++) writeBYTE(command[i]);    // send all chars to serial port
    while (!_cmd.readable()) wait_ms(TEMPO);    // wait for screen answer
    while (_cmd.readable() && resp < ARRAY_SIZE(response)) {
        temp = _cmd.getc();
        response[resp++] = (char)temp;
    }
    switch (resp) {
        case 4 :
            resp = (int)response[1];         // if OK populate data
            break;
        default :
            resp =  -1;                      // else return   0
            break;
    }
#if DEBUGMODE
    pc.printf("   Answer received : %d\n", resp);
#endif
    return resp;
}
            
    