Graphical demo for the LPC4088 Experiment Base Board with one of the Display Expansion Kits. This program displays how to use the emWin library from Segger.

Dependencies:   EALib ewgui mbed

This program requires the emWin library. Instructions and more information.

Files at this revision

API Documentation at this revision

Comitter:
embeddedartists
Date:
Tue Jul 14 11:34:15 2015 +0000
Commit message:
First version

Changed in this revision

AR1021I2C.cpp Show annotated file Show diff for this revision Revisions of this file
AR1021I2C.h Show annotated file Show diff for this revision Revisions of this file
EALib.lib Show annotated file Show diff for this revision Revisions of this file
EaLcdBoardGPIO.cpp Show annotated file Show diff for this revision Revisions of this file
EaLcdBoardGPIO.h Show annotated file Show diff for this revision Revisions of this file
EwGuiImpl.cpp Show annotated file Show diff for this revision Revisions of this file
EwGuiImpl.h Show annotated file Show diff for this revision Revisions of this file
Graphics.cpp Show annotated file Show diff for this revision Revisions of this file
Graphics.h Show annotated file Show diff for this revision Revisions of this file
MyWindow.cpp Show annotated file Show diff for this revision Revisions of this file
MyWindow.h Show annotated file Show diff for this revision Revisions of this file
ewgui.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r 7f5765fcd048 AR1021I2C.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AR1021I2C.cpp	Tue Jul 14 11:34:15 2015 +0000
@@ -0,0 +1,562 @@
+/*
+ *  Copyright 2013 Embedded Artists AB
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+/******************************************************************************
+ * Includes
+ *****************************************************************************/
+
+#include "mbed.h"
+#include "mbed_debug.h"
+
+#include "AR1021I2C.h"
+
+/******************************************************************************
+ * Defines and typedefs
+ *****************************************************************************/
+
+#define AR1021_REG_TOUCH_THRESHOLD        (0x02)
+#define AR1021_REG_SENS_FILTER            (0x03)
+#define AR1021_REG_SAMPLING_FAST          (0x04)
+#define AR1021_REG_SAMPLING_SLOW          (0x05)
+#define AR1021_REG_ACC_FILTER_FAST        (0x06)
+#define AR1021_REG_ACC_FILTER_SLOW        (0x07)
+#define AR1021_REG_SPEED_THRESHOLD        (0x08)
+#define AR1021_REG_SLEEP_DELAY            (0x0A)
+#define AR1021_REG_PEN_UP_DELAY           (0x0B)
+#define AR1021_REG_TOUCH_MODE             (0x0C)
+#define AR1021_REG_TOUCH_OPTIONS          (0x0D)
+#define AR1021_REG_CALIB_INSETS           (0x0E)
+#define AR1021_REG_PEN_STATE_REPORT_DELAY (0x0F)
+#define AR1021_REG_TOUCH_REPORT_DELAY     (0x11)
+
+
+#define AR1021_CMD_GET_VERSION                 (0x10)
+#define AR1021_CMD_ENABLE_TOUCH                (0x12)
+#define AR1021_CMD_DISABLE_TOUCH               (0x13)
+#define AR1021_CMD_CALIBRATE_MODE              (0x14)
+#define AR1021_CMD_REGISTER_READ               (0x20)
+#define AR1021_CMD_REGISTER_WRITE              (0x21)
+#define AR1021_CMD_REGISTER_START_ADDR_REQUEST (0x22)
+#define AR1021_CMD_REGISTER_WRITE_TO_EEPROM    (0x23)
+#define AR1021_CMD_EEPROM_READ                 (0x28)
+#define AR1021_CMD_EEPROM_WRITE                (0x29)
+#define AR1021_CMD_EEPROM_WRITE_TO_REGISTERS   (0x2B)
+
+#define AR1021_RESP_STAT_OK           (0x00)
+#define AR1021_RESP_STAT_CMD_UNREC    (0x01)
+#define AR1021_RESP_STAT_HDR_UNREC    (0x03)
+#define AR1021_RESP_STAT_TIMEOUT      (0x04)
+#define AR1021_RESP_STAT_CANCEL_CALIB (0xFC)
+
+
+#define AR1021_ERR_NO_HDR      (-1000)
+#define AR1021_ERR_INV_LEN     (-1001)
+#define AR1021_ERR_INV_RESP    (-1002)
+#define AR1021_ERR_INV_RESPLEN (-1003)
+#define AR1021_ERR_TIMEOUT     (-1004)
+
+// bit 7 is always 1 and bit 0 defines pen up or down
+#define AR1021_PEN_MASK (0x81)
+
+#define AR1021_NUM_CALIB_POINTS (4)
+
+#define AR1021_ADDR  (0x4D << 1)
+
+#define AR1021_TIMEOUT     1000        //how many ms to wait for responce 
+#define AR1021_RETRY          5        //how many times to retry sending command 
+
+#define AR1021_MIN(__a, __b) (((__a)<(__b))?(__a):(__b))
+
+
+AR1021I2C::AR1021I2C(PinName sda, PinName scl, PinName siq) :
+_i2c(sda, scl), _siq(siq), _siqIrq(siq)
+{
+    _i2c.frequency(200000);
+
+    // default calibration inset is 25 -> (25/2 = 12.5%)
+    _inset = 25;
+
+    // make sure _calibPoint has an invalid value to begin with
+    // correct value is set in calibrateStart()
+    _calibPoint = AR1021_NUM_CALIB_POINTS+1;
+
+    _x = 0;
+    _y = 0;
+    _pen = 0;
+
+    _initialized = false;
+}
+
+
+bool AR1021I2C::read(touchCoordinate_t &coord) {
+
+    if (!_initialized) return false;
+
+    coord.x = _x * _width/4095;
+    coord.y = _y * _height/4095;
+    coord.z = _pen;
+
+    return true;
+}
+
+
+bool AR1021I2C::init(uint16_t width, uint16_t height) {
+    int result = 0;
+    bool ok = false;
+    int attempts = 0;
+
+    _width = width;
+    _height = height;
+
+    while (1) {
+
+        do {
+            // disable touch
+            result = cmd(AR1021_CMD_DISABLE_TOUCH, NULL, 0, NULL, 0);
+            if (result != 0) {
+                debug("disable touch failed (%d)\n", result);
+                break;
+            }
+
+            char regOffset = 0;
+            int regOffLen = 1;
+            result = cmd(AR1021_CMD_REGISTER_START_ADDR_REQUEST, NULL, 0,
+                    &regOffset, &regOffLen);
+            if (result != 0) {
+                debug("register offset request failed (%d)\n", result);
+                break;
+            }
+
+            // enable calibrated coordinates
+            //                  high, low address,                        len,  value
+            char toptions[4] = {0x00, AR1021_REG_TOUCH_OPTIONS+regOffset, 0x01, 0x01};
+            result = cmd(AR1021_CMD_REGISTER_WRITE, toptions, 4, NULL, 0);
+            if (result != 0) {
+                debug("register write request failed (%d)\n", result);
+                break;
+            }
+
+            // save registers to eeprom
+            result = cmd(AR1021_CMD_REGISTER_WRITE_TO_EEPROM, NULL, 0, NULL, 0);
+            if (result != 0) {
+                debug("register write to eeprom failed (%d)\n", result);
+                break;
+            }
+
+            // enable touch
+            result = cmd(AR1021_CMD_ENABLE_TOUCH, NULL, 0, NULL, 0);
+            if (result != 0) {
+                debug("enable touch failed (%d)\n", result);
+                break;
+            }
+
+            _siqIrq.rise(this, &AR1021I2C::readTouchIrq);
+
+            _initialized = true;
+            ok = true;
+
+        } while(0);
+
+        if (ok) break;
+
+        // try to run the initialize sequence at most 2 times
+        if(++attempts >= 2) break;
+    }
+
+
+    return ok;
+}
+
+bool AR1021I2C::calibrateStart() {
+    bool ok = false;
+    int result = 0;
+    int attempts = 0;
+
+    if (!_initialized) return false;
+
+    _siqIrq.rise(NULL);
+
+    while(1) {
+
+        do {
+            // disable touch
+            result = cmd(AR1021_CMD_DISABLE_TOUCH, NULL, 0, NULL, 0);
+            if (result != 0) {
+                debug("disable touch failed (%d)\n", result);
+                break;
+            }
+
+            char regOffset = 0;
+            int regOffLen = 1;
+            result = cmd(AR1021_CMD_REGISTER_START_ADDR_REQUEST, NULL, 0,
+                    &regOffset, &regOffLen);
+            if (result != 0) {
+                debug("register offset request failed (%d)\n", result);
+                break;
+            }
+
+            // set insets
+            // enable calibrated coordinates
+            //                high, low address,                       len,  value
+            char insets[4] = {0x00, AR1021_REG_CALIB_INSETS+regOffset, 0x01, _inset};
+            result = cmd(AR1021_CMD_REGISTER_WRITE, insets, 4, NULL, 0);
+            if (result != 0) {
+                debug("register write request failed (%d)\n", result);
+                break;
+            }
+
+            // calibration mode
+            char calibType = 4;
+            result = cmd(AR1021_CMD_CALIBRATE_MODE, &calibType, 1, NULL, 0, false);
+            if (result != 0) {
+                debug("calibration mode failed (%d)\n", result);
+                break;
+            }
+
+            _calibPoint = 0;
+            ok = true;
+
+        } while(0);
+
+        if (ok) break;
+
+        // try to run the calibrate mode sequence at most 2 times
+        if (++attempts >= 2) break;
+    }
+
+    return ok;
+}
+
+bool AR1021I2C::getNextCalibratePoint(uint16_t* x, uint16_t* y) {
+
+    if (!_initialized) return false;
+    if (x == NULL || y == NULL) return false;
+
+    int xInset = (_width * _inset / 100) / 2;
+    int yInset = (_height * _inset / 100) / 2;
+
+    switch(_calibPoint) {
+    case 0:
+        *x = xInset;
+        *y = yInset;
+        break;
+    case 1:
+        *x = _width - xInset;
+        *y = yInset;
+        break;
+    case 2:
+        *x = _width - xInset;
+        *y = _height - yInset;
+        break;
+    case 3:
+        *x = xInset;
+        *y = _height - yInset;
+        break;
+    default:
+        return false;
+    }
+
+    return true;
+}
+
+bool AR1021I2C::waitForCalibratePoint(bool* morePoints, uint32_t timeout) {
+    int result = 0;
+    bool ret = false;
+
+    if (!_initialized) return false;
+
+    do {
+        if (morePoints == NULL || _calibPoint >= AR1021_NUM_CALIB_POINTS) {
+            break;
+        }
+
+        // wait for response
+        result = waitForCalibResponse(timeout);
+        if (result != 0) {
+            debug("wait for calibration response failed (%d)\n", result);
+            break;
+        }
+
+        _calibPoint++;
+        *morePoints = (_calibPoint < AR1021_NUM_CALIB_POINTS);
+
+
+        // no more points -> enable touch
+        if (!(*morePoints)) {
+
+            // wait for calibration data to be written to eeprom
+            // before enabling touch
+            result = waitForCalibResponse(timeout);
+            if (result != 0) {
+                debug("wait for calibration response failed (%d)\n", result);
+                break;
+            }
+
+
+            // clear chip-select since calibration is done;
+//            _cs = 1;
+
+            result = cmd(AR1021_CMD_ENABLE_TOUCH, NULL, 0, NULL, 0);
+            if (result != 0) {
+                debug("enable touch failed (%d)\n", result);
+                break;
+            }
+
+            _siqIrq.rise(this, &AR1021I2C::readTouchIrq);
+        }
+
+        ret = true;
+
+    } while (0);
+
+
+
+    if (!ret) {
+        // make sure to set chip-select off in case of an error
+//        _cs = 1;
+        // calibration must restart if an error occurred
+        _calibPoint = AR1021_NUM_CALIB_POINTS+1;
+    }
+
+
+
+    return ret;
+}
+
+int AR1021I2C::cmd(char cmd, char* data, int len, char* respBuf, int* respLen,
+        bool setCsOff) {
+
+    int ret = 0;
+    int readLen = (respLen == NULL) ? 0 : *respLen;
+    for (int attempt = 1; attempt <= AR1021_RETRY; attempt++) {
+        if (attempt > 1) {
+            wait_ms(50);
+        }
+
+        // command request
+        // ---------------
+        // 0x00 0x55 len cmd data
+        // 0x00 = protocol command byte
+        // 0x55 = header
+        // len = data length + cmd (1)
+        // data = data to send
+
+        _i2c.start(); 
+        _i2c.write(AR1021_ADDR);                   //send write address 
+        _i2c.write(0x00); 
+        _i2c.write(0x55);                          //header 
+        _i2c.write(len+1);                         //message length 
+        _i2c.write(cmd);
+        for (int i = 0; i < len; i++) {
+            _i2c.write(data[i]);
+        }
+        wait_us(60);
+        _i2c.stop();
+     
+        // wait for response (siq goes high when response is available)
+        Timer t;
+        t.start();
+        while(_siq.read() != 1 && t.read_ms() < AR1021_TIMEOUT);
+        
+        if (t.read_ms() < AR1021_TIMEOUT) {
+        
+            // command response
+            // ---------------
+            // 0x55 len status cmd data
+            // 0x55 = header
+            // len = number of bytes following the len byte (i.e. including the status&cmd)
+            // status = status
+            // cmd = command ID
+            // data = data to receive
+            _i2c.start();
+            _i2c.write(AR1021_ADDR + 1);        //send read address 
+            char header = _i2c.read(1);         //header should always be 0x55
+            if (header != 0x55) {
+                ret = AR1021_ERR_NO_HDR;
+                continue;
+            }
+            char length = _i2c.read(1);         //data length
+            if (length < 2) {
+                ret = AR1021_ERR_INV_LEN;       //must have at least status and command bytes
+                continue;
+            }
+            length -= 2;
+            if (length > readLen) {
+                ret = AR1021_ERR_INV_LEN;       //supplied buffer is not enough
+                continue;
+            }
+
+            char status = _i2c.read(1);         //command status
+            char usedCmd;
+            if (readLen <= 0) {
+                usedCmd = _i2c.read(0);         //no data => read command byte + NACK
+            } else {
+                usedCmd = _i2c.read(1);         //which command
+
+                //we need to send a NACK on the last read. 
+                int i;
+                for (i = 0; i < (length-1); i++) {
+                    respBuf[i] = _i2c.read(1);
+                }
+                respBuf[i] = _i2c.read(0);      //last returned data byte + NACK
+            }
+            _i2c.stop();
+            
+            
+            if (status != AR1021_RESP_STAT_OK) {
+                ret = -status;
+                continue;
+            }
+            if (usedCmd != cmd) {
+                ret = AR1021_ERR_INV_RESP;
+                continue;
+            }
+            
+            // success
+            ret = 0;
+            break;
+            
+        } else {
+            ret = AR1021_ERR_TIMEOUT;
+            continue;
+        }
+    }
+
+    return ret;
+}
+
+int AR1021I2C::waitForCalibResponse(uint32_t timeout) {
+    Timer t;
+    int ret = 0;
+
+    t.start();
+
+    // wait for siq
+    while (_siq.read() != 1 &&
+            (timeout == 0 || (uint32_t)t.read_ms() < (int)timeout));
+
+
+    do {
+
+        if (timeout >  0 && (uint32_t)t.read_ms() >= timeout) {
+            ret = AR1021_ERR_TIMEOUT;
+            break;
+        }
+
+        // command response
+        // ---------------
+        // 0x55 len status cmd data
+        // 0x55 = header
+        // len = number of bytes following the len byte (should be 2)
+        // status = status
+        // cmd = command ID
+        _i2c.start();
+        _i2c.write(AR1021_ADDR + 1);        //send read address 
+        char header = _i2c.read(1);         //header should always be 0x55  
+        char length = _i2c.read(1);         //data length
+
+        if (header != 0x55) {
+            ret = AR1021_ERR_NO_HDR;
+            break;
+        }
+        if (length < 2) {
+            ret = AR1021_ERR_INV_LEN;
+            break;
+        }
+        char status = _i2c.read(1);         //status
+        char cmd    = _i2c.read(0);         //command, should be NACK'ed
+        _i2c.stop();
+        if (status != AR1021_RESP_STAT_OK) {
+            ret = -status;
+            break;
+        }
+        if (cmd != AR1021_CMD_CALIBRATE_MODE) {
+            ret = AR1021_ERR_INV_RESP;
+            break;
+        }
+        
+        // success
+        ret = 0;
+
+    } while (0);
+
+    return ret;
+}
+
+
+void AR1021I2C::readTouchIrq() {
+    while(_siq.read() == 1) {
+
+        // touch coordinates are sent in a 5-byte data packet
+        _i2c.start();
+        _i2c.write(AR1021_ADDR + 1);        //send read address 
+        int pen = _i2c.read(1);
+        int xlo = _i2c.read(1);
+        int xhi = _i2c.read(1);
+        int ylo = _i2c.read(1);
+        int yhi = _i2c.read(0);
+        _i2c.stop();
+        
+        // pen down
+        if ((pen&AR1021_PEN_MASK) == (1<<7|1<<0)) {
+            _pen = 1;
+        }
+        // pen up
+        else if ((pen&AR1021_PEN_MASK) == (1<<7)){
+            _pen = 0;
+        }
+        // invalid value
+        else {
+            continue;
+        }
+
+        _x = ((xhi<<7)|xlo);
+        _y = ((yhi<<7)|ylo);
+    }
+}
+
+bool AR1021I2C::info(int* verHigh, int* verLow, int* resBits, int* type)
+{
+    char buff[3] = {0,0,0};
+    int read = 3;
+    int res = cmd(AR1021_CMD_GET_VERSION, NULL, 0, buff, &read);
+    if (res == 0) {
+        *verHigh = buff[0];
+        *verLow = buff[1];
+        switch(buff[2] & 3) {
+            case 0:   
+                *resBits = 8;
+                break;
+            case 1:   
+                *resBits = 10;
+                break;
+            case 2:   
+                *resBits = 12;
+                break;
+            case 3:   
+                *resBits = 12;
+                break;
+            default:
+                res = 25;
+                printf("Invalid resolution %d\n", buff[2]&3);
+                break;
+        }
+        *type = buff[2]>>2;
+    }
+    return (res == 0);
+}
+
+
diff -r 000000000000 -r 7f5765fcd048 AR1021I2C.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AR1021I2C.h	Tue Jul 14 11:34:15 2015 +0000
@@ -0,0 +1,79 @@
+/*
+ *  Copyright 2013 Embedded Artists AB
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+#ifndef AR1021I2C_H
+#define AR1021I2C_H
+
+#include "TouchPanel.h"
+
+/**
+ * Microchip Touch Screen Controller (AR1021).
+ *
+ * Please note that this touch panel has an on-board storage for
+ * calibration data. Once a successful calibration has been performed
+ * it is not needed to do additional calibrations since the stored
+ * calibration data will be used.
+ */
+class AR1021I2C : public TouchPanel {
+public:
+
+
+    /**
+     * Constructor
+     *
+     * @param mosi I2C SDA pin
+     * @param miso I2C SCL pin
+     * @param siq interrupt pin
+     */
+    AR1021I2C(PinName sda, PinName scl, PinName siq);
+
+    bool info(int* verHigh, int* verLow, int* resBits, int* type);
+
+    virtual bool init(uint16_t width, uint16_t height);
+    virtual bool read(touchCoordinate_t &coord);
+    virtual bool calibrateStart();
+    virtual bool getNextCalibratePoint(uint16_t* x, uint16_t* y);
+    virtual bool waitForCalibratePoint(bool* morePoints, uint32_t timeout);
+
+private:
+
+
+    I2C _i2c;
+    DigitalIn _siq;
+    InterruptIn _siqIrq;
+    bool _initialized;
+
+
+    int32_t _x;
+    int32_t _y;
+    int32_t _pen;
+
+    uint16_t _width;
+    uint16_t _height;
+    uint8_t _inset;
+
+    int _calibPoint;
+
+
+    int cmd(char cmd, char* data, int len, char* respBuf, int* respLen, bool setCsOff=true);
+    int waitForCalibResponse(uint32_t timeout);
+    void readTouchIrq();
+};
+
+#endif
+
+
+
diff -r 000000000000 -r 7f5765fcd048 EALib.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EALib.lib	Tue Jul 14 11:34:15 2015 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/embeddedartists/code/EALib/#e1e36493f347
diff -r 000000000000 -r 7f5765fcd048 EaLcdBoardGPIO.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EaLcdBoardGPIO.cpp	Tue Jul 14 11:34:15 2015 +0000
@@ -0,0 +1,98 @@
+/*
+ *  Copyright 2013 Embedded Artists AB
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+/******************************************************************************
+ * Includes
+ *****************************************************************************/
+
+#include "mbed.h"
+#include "EaLcdBoardGPIO.h"
+
+/******************************************************************************
+ * Defines and typedefs
+ *****************************************************************************/
+
+
+EaLcdBoardGPIO::EaLcdBoardGPIO(PinName sda, PinName scl)
+  : EaLcdBoard(sda, scl), /*pinWP(P4_15),*/ pin3v3(P2_0), pin5v(P2_21), pinDE(P2_11), pinContrast(P2_1)
+{
+  pinContrast.period_ms(10);
+  setWriteProtect(true);
+  set3V3Signal(false);
+  set5VSignal(false);
+  setDisplayEnableSignal(false);
+  setBacklightContrast(0);
+}
+
+
+void EaLcdBoardGPIO::setWriteProtect(bool enable)
+{  
+    // Not Applicable
+}
+
+void EaLcdBoardGPIO::set3V3Signal(bool enabled) { //P2.0 L=3.3V on
+    if (enabled) {
+        pin3v3 = 0;
+    } else {
+        pin3v3 = 1;
+    }
+}
+
+void EaLcdBoardGPIO::set5VSignal(bool enabled) { //P2.21 H=5V on
+    if (enabled) {
+        pin5v = 1;
+    } else {
+        pin5v = 0;
+    }
+}
+
+void EaLcdBoardGPIO::setDisplayEnableSignal(bool enabled) { //P2.11 H=enabled
+    LPC_IOCON->P2_11 &= ~7; /* GPIO2[11]  @ P2.11 */
+    if (enabled) {
+        pinDE = 1;
+    } else {
+        pinDE = 0;
+    }
+}
+
+void EaLcdBoardGPIO::setBacklightContrast(uint32_t value) { //P2.1, set to 4.30 for now
+#if 0    
+    LPC_IOCON->P2_1 &= ~7; /* GPIO2[1]  @ P2.1 */
+  if (value > 50) {
+      pinContrast = 1;
+  } else {
+      pinContrast = 0;
+  }
+#else
+    uint32_t tmp = LPC_IOCON->P2_1;
+    tmp &= ~7;
+    tmp |= 1;
+    LPC_IOCON->P2_1 = tmp; /* PWM2[1]  @ P2.1 */
+    float f = value;
+    pinContrast = f/100.0f;
+#endif
+  
+//    if (value > 100) return;
+
+//    pca9532_setBlink0Duty(100-value);
+//    pca9532_setBlink0Period(0);
+//    pca9532_setBlink0Leds(LCDB_CTRL_BL_C);
+}
+
+
+
+
+
diff -r 000000000000 -r 7f5765fcd048 EaLcdBoardGPIO.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EaLcdBoardGPIO.h	Tue Jul 14 11:34:15 2015 +0000
@@ -0,0 +1,52 @@
+/*
+ *  Copyright 2013 Embedded Artists AB
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+#ifndef EALCDBOARDGPIO_H
+#define EALCDBOARDGPIO_H
+
+#include "EaLcdBoard.h"
+
+/** An interface to Embedded Artists LCD Boards
+ *
+ */
+class EaLcdBoardGPIO : public EaLcdBoard {
+public:
+
+    EaLcdBoardGPIO(PinName sda, PinName scl);
+
+    void setBC(uint32_t val) { setBacklightContrast(val); };
+
+protected:
+    virtual void setWriteProtect(bool enable);
+    virtual void set3V3Signal(bool enabled);
+    virtual void set5VSignal(bool enabled);
+    virtual void setDisplayEnableSignal(bool enabled);
+    virtual void setBacklightContrast(uint32_t value);
+
+private:
+    //DigitalOut pinWP;
+    DigitalOut pin3v3;
+    DigitalOut pin5v;
+    DigitalOut pinDE;
+    //DigitalOut pinContrast;
+    PwmOut pinContrast;
+};
+
+#endif
+
+
+
+
diff -r 000000000000 -r 7f5765fcd048 EwGuiImpl.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EwGuiImpl.cpp	Tue Jul 14 11:34:15 2015 +0000
@@ -0,0 +1,206 @@
+#include "EwGuiImpl.h"
+
+#include "LcdController.h"
+#include "EaLcdBoardGPIO.h"
+#include "sdram.h"
+#include "AR1021I2C.h"
+
+
+#define PIXEL_SIZE (2)
+
+#define LCD_CONFIGURATION_43 \
+        40,                         /* horizontalBackPorch */ \
+        5,                          /* horizontalFrontPorch */ \
+        2,                          /* hsync */ \
+        480,                        /* width */ \
+        8,                          /* verticalBackPorch */ \
+        8,                          /* verticalFrontPorch */ \
+        2,                          /* vsync */ \
+        272,                        /* height */ \
+        false,                      /* invertOutputEnable */ \
+        false,                      /* invertPanelClock */ \
+        true,                       /* invertHsync */ \
+        true,                       /* invertVsync */ \
+        1,                          /* acBias */ \
+        LcdController::Bpp_16_565,  /* bpp */ \
+        9000000,                    /* optimalClock */ \
+        LcdController::Tft,         /* panelType */ \
+        false                       /* dualPanel */
+
+#define LCD_INIT_STRING_43  (char*)"v1,cd0,c50,cc0,c30,d100,c31,d100,cd1,d10,o,c51,cc100"
+
+#define LCD_CONFIGURATION_50 \
+        46,                         /* horizontalBackPorch */ \
+        20,                          /* horizontalFrontPorch */ \
+        2,                          /* hsync */ \
+        800,                        /* width */ \
+        23,                          /* verticalBackPorch */ \
+        10,                          /* verticalFrontPorch */ \
+        3,                          /* vsync */ \
+        480,                        /* height */ \
+        false,                      /* invertOutputEnable */ \
+        false,                      /* invertPanelClock */ \
+        true,                       /* invertHsync */ \
+        true,                       /* invertVsync */ \
+        1,                          /* acBias */ \
+        LcdController::Bpp_16_565,  /* bpp */ \
+        30000000,                   /* optimalClock */ \
+        LcdController::Tft,         /* panelType */ \
+        false                       /* dualPanel */
+
+#define LCD_INIT_STRING_50  (char*)"v1,cc0,c31,d50,o,d200,c51,cc100"
+
+EwGuiImpl::EwGuiImpl(WhichDisplay which) {
+
+    EaLcdBoardGPIO lcdBoard(P0_27, P0_28);
+    EaLcdBoardGPIO::Result result;
+	  LcdController::Config* lcdCfg;
+
+    do {
+
+				switch (which) {
+						case TFT_5:
+								lcdCfg = new LcdController::Config(LCD_CONFIGURATION_50);
+							  result = lcdBoard.open(lcdCfg, LCD_INIT_STRING_50);
+								break;
+						case TFT_4_3:
+								lcdCfg = new LcdController::Config(LCD_CONFIGURATION_43);
+							  result = lcdBoard.open(lcdCfg, LCD_INIT_STRING_43);
+								break;
+						default:
+								mbed_die();
+				}
+        
+        if (result != EaLcdBoard::Ok) {
+            printf("Failed to open display: %d\n", result);
+            break;
+        }
+
+        _width = lcdCfg->width;
+        _height = lcdCfg->height;
+
+        // allocate buffer, width x height x 2 (2 bytes = 16 bit color data)
+        _fb = (uint32_t)malloc(_width*_height*PIXEL_SIZE);
+        if (_fb == 0) {
+            printf("Failed to allocate frame buffer\n");
+            break;
+        }
+
+        result = lcdBoard.setFrameBuffer(_fb);
+        if (result != EaLcdBoard::Ok) {
+            printf("Failed to activate frameBuffer: %d\n", result);
+            break;
+        }
+
+        _memSz = 1024*1024*5;
+        _mem = (uint32_t)malloc(_memSz);
+        if (_mem == 0) {
+            printf("Failed to allocate memory block for emwin\n");
+            break;
+        }
+
+
+        memset((void*)_fb, 0x0, _width*_height*PIXEL_SIZE);
+
+        // create touch panel
+				_touch = new AR1021I2C(P0_27, P0_28, P2_25);
+
+        if (!_touch->init(_width, _height)) {
+            printf("TouchPanel.init failed\n");
+            break;
+        }
+
+        init();
+
+    } while(0);
+
+
+}
+
+void* EwGuiImpl::getMemoryBlockAddress() {
+    return (void*)_mem;
+}
+
+uint32_t EwGuiImpl::getMemoryBlockSize() {
+    return _memSz;
+}
+
+uint32_t EwGuiImpl::getDisplayWidth() {
+    return _width;
+}
+
+uint32_t EwGuiImpl::getDisplayHeight() {
+    return _height;
+}
+
+void* EwGuiImpl::getFrameBufferAddress() {
+    return (void*)_fb;
+}
+
+void EwGuiImpl::getTouchValues(int32_t* x, int32_t* y, int32_t* z) {
+
+    if (!x || !y || !z) return;
+
+    TouchPanel::touchCoordinate_t coord;
+    _touch->read(coord);
+
+    *x = coord.x;
+    *y = coord.y;
+    *z = coord.z;
+}
+
+void EwGuiImpl::calibrate() {
+
+    uint16_t x = 0;
+    uint16_t y = 0;
+    bool hasMorePoints = false;
+
+    EwPainter painter;
+    painter.saveContext();
+
+    do {
+
+        printf("Starting calibration\n");
+        if (!_touch->calibrateStart()) {
+            printf("Failed to start calibration\n");
+            break;
+        }
+
+        do {
+            if (!_touch->getNextCalibratePoint(&x, &y)) {
+                printf("Failed to get next calibrate point\n");
+                break;
+            }
+
+            printf("calib: x=%d, y=%d\n", x, y);
+            drawCalibPoint(painter, x, y);
+
+            if (!_touch->waitForCalibratePoint(&hasMorePoints, 0)) {
+                printf("Failed waiting for calibration point\n");
+                break;
+            }
+
+        } while(hasMorePoints);
+
+        printf("Calibration done\n");
+
+
+    } while (0);
+
+
+    painter.clear();
+    painter.restoreContext();
+}
+
+void EwGuiImpl::drawCalibPoint(EwPainter &painter, int32_t x, int32_t y) {
+
+    painter.clear();
+    painter.setColor(EW_WHITE);
+    painter.drawStringHorizCenter("Touch circle to calibrate",
+            getDisplayWidth()/2, getDisplayHeight()/2);
+
+    painter.fillCircle(x, y, 10);
+    painter.setColor(EW_BLACK);
+    painter.fillCircle(x, y, 5);
+}
+
diff -r 000000000000 -r 7f5765fcd048 EwGuiImpl.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EwGuiImpl.h	Tue Jul 14 11:34:15 2015 +0000
@@ -0,0 +1,46 @@
+
+#ifndef EWGUIIMPL_H
+#define EWGUIIMPL_H
+
+#include "mbed.h"
+#include "EwGui.h"
+#include "EwPainter.h"
+#include "TouchPanel.h"
+
+class EwGuiImpl : public EwGui {
+public:
+
+	  enum WhichDisplay {
+	      TFT_5,    // 5" display
+	      TFT_4_3,  // 4.3" display
+	  };
+
+    EwGuiImpl(WhichDisplay which);
+
+    virtual void* getMemoryBlockAddress();
+    virtual uint32_t getMemoryBlockSize();
+
+    virtual uint32_t getDisplayWidth();
+    virtual uint32_t getDisplayHeight();
+
+    virtual void* getFrameBufferAddress();
+
+    virtual void getTouchValues(int32_t* x, int32_t* y, int32_t* z);
+
+    void calibrate();
+
+
+private:
+
+    uint32_t _width;
+    uint32_t _height;
+    uint32_t _fb;
+    uint32_t _mem;
+    uint32_t _memSz;
+    TouchPanel* _touch;
+
+    void drawCalibPoint(EwPainter &painter, int32_t x, int32_t y);
+};
+
+#endif
+
diff -r 000000000000 -r 7f5765fcd048 Graphics.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Graphics.cpp	Tue Jul 14 11:34:15 2015 +0000
@@ -0,0 +1,243 @@
+
+#include "mbed.h"
+#include "Graphics.h"
+
+
+Graphics::Graphics(uint16_t *pFrmBuf, uint16_t dispWidth, uint16_t dispHeight)
+{
+	this->windowX = dispWidth;
+	this->windowY = dispHeight;
+	this->pFrmBuf = pFrmBuf;
+}
+
+void Graphics::setFrameBuffer( uint16_t *pFrmBuf )
+{
+	this->pFrmBuf = pFrmBuf;
+}
+
+int32_t Graphics::abs(int32_t v1) const
+{
+   if (v1 > 0)
+     return v1;
+
+  return -v1;
+}
+
+/***********************************************************************
+ *
+ * Function: swim_put_line_raw
+ *
+ * Purpose: Draw a line on the physical display
+ *
+ * Processing:
+ *     See function.
+ *
+ * Parameters:
+ *     win : Window identifier
+ *     x1  : Physical X position of X line start
+ *     y1  : Physical Y position of Y line start
+ *     x2  : Physical X position of X line end
+ *     y2  : Physical Y position of Y line end
+ *
+ * Outputs: None
+ *
+ * Returns: Nothing
+ *
+ * Notes: None
+ *
+ **********************************************************************/
+void Graphics::put_line(int32_t x1, int32_t y1, int32_t x2, int32_t y2, int16_t color)
+{
+    int32_t e2, sx, sy, dx, dy, err;
+    
+    /* calculate delta_x and delta_y */
+    dx = abs(x2 - x1);
+    dy = abs(y2 - y1);
+
+    /* set the direction for the step for both x and y, and
+       initialize the error */
+    if (x1 < x2)
+        sx = 1;
+    else
+        sx = -1;
+
+    if (y1 < y2)
+        sy = 1;
+    else
+        sy = -1;
+
+    err = dx - dy;
+   
+    while (1)
+    {
+        if ((x1 >= 0) && (x1 < this->windowX) && 
+            (y1 >= 0) && (y1 < this->windowY))
+            this->pFrmBuf[x1 + (this->windowX*y1)] = color;
+
+        if ((x1 == x2) && (y1 == y2))
+            return;
+
+        e2 = 2 * err;
+        if (e2 > -dy)
+        {
+            err -= dy;
+            x1 += sx;
+        }
+        if (e2 < dx)
+        {
+            err += dx;
+            y1 += sy;
+        }
+    }
+}
+
+/***********************************************************************
+ *
+ * Function: plot4points
+ *
+ * Purpose:
+ *
+ * Processing:
+ *     See function.
+ *
+ * Parameters:
+ *     win    : Window identifier
+ *     cx     :
+ *     cy     :
+ *     x      :
+ *     y      :
+ *     Filled :
+ *
+ * Outputs: None
+ *
+ * Returns: Nothing
+ *
+ * Notes: None
+ *
+ **********************************************************************/
+void Graphics::plot4points( int32_t cx, int32_t cy, int32_t x, int32_t y, int16_t color, int32_t Filled )
+   {
+   int16_t x0, x1, y0, y1;
+
+   y0 = cy + y;
+   y1 = cy - y;
+   if( Filled )
+      {
+      for( x0=cx - x; x0<=cx + x; x0++ )
+         {
+         if ((x0>=0) && (x0<this->windowX) && (y0>=0) && (y0<this->windowY))
+            this->pFrmBuf[x0 + (this->windowX*y0)] = color;
+         if ((x0>=0) && (x0<this->windowX) && (y1>=0) && (y1<this->windowY))
+            this->pFrmBuf[x0 + (this->windowX*y1)] = color;
+         }
+      }
+   else
+      {
+      x0 = cx + x;
+      x1 = cx - x;
+      if ((x0>=0) && (x0<this->windowX) && (y0>=0) && (y0<this->windowY))
+         this->pFrmBuf[x0 + (this->windowX*y0)] = color;
+      if ((x != 0) && 
+          (x1>=0) && (x1<this->windowX) && (y0>=0) && (y0<this->windowY))
+         this->pFrmBuf[x1 + (this->windowX*y0)] = color;
+      if ((y != 0) &&
+          (x0>=0) && (x0<this->windowX) && (y1>=0) && (y1<this->windowY))
+         this->pFrmBuf[x0 + (this->windowX*y1)] = color;
+      if ((x != 0 && y != 0) &&
+          (x1>=0) && (x1<this->windowX) && (y1>=0) && (y1<this->windowY))
+         this->pFrmBuf[x1 + (this->windowX*y1)] = color;
+      }
+   }
+
+/***********************************************************************
+ *
+ * Function: plot8points
+ *
+ * Purpose:
+ *
+ * Processing:
+ *     See function.
+ *
+ * Parameters:
+ *     win    : Window identifier
+ *     cx     :
+ *     cy     :
+ *     x      :
+ *     y      :
+ *     Filled :
+ *
+ * Outputs: None
+ *
+ * Returns: Nothing
+ *
+ * Notes: None
+ *
+ **********************************************************************/
+void Graphics::plot8points( int32_t cx, int32_t cy, int32_t x, int32_t y, int16_t color, int32_t Filled )
+   {
+   plot4points( cx, cy, x, y, color, Filled );
+   if (x != y)
+      plot4points( cx, cy, y, x, color, Filled );
+   }
+
+/***********************************************************************
+ *
+ * Function: swim_put_circle
+ *
+ * Purpose:
+ *
+ * Processing:
+ *     See function.
+ *
+ * Parameters:
+ *     win    : Window identifier
+ *     cx     :
+ *     cy     :
+ *     radius :
+ *     Filled :
+ *
+ * Outputs: None
+ *
+ * Returns: Nothing
+ *
+ * Notes: None
+ *
+ **********************************************************************/
+void Graphics::put_circle( int32_t cx, int32_t cy, int16_t color, int32_t radius, int32_t Filled )
+   {
+   int32_t Error = -radius;
+   int16_t x = radius;
+   int16_t y = 0;
+
+   while( x >= y )
+      {
+      plot8points( cx, cy, x, y, color, Filled );
+
+      Error += y;
+      ++y;
+      Error += y;
+
+      if( Error >= 0 )
+         {
+         --x;
+         Error -= x;
+         Error -= x;
+         }
+      }
+   }
+
+void Graphics::put_dot( int32_t cx, int32_t cy, int16_t color )
+{
+  int size = 1;
+  for (int y1 = cy - size; y1 <= (cy + size); y1++) {
+    for (int x1 = cx - size; x1 <= (cx + size); x1++) {
+      if ((x1 >= 0) && (x1 < this->windowX) && (y1 >= 0) && (y1 < this->windowY)) {
+          this->pFrmBuf[x1 + (this->windowX*y1)] = color;
+      }
+    }
+  }
+}
+
+
+
+
diff -r 000000000000 -r 7f5765fcd048 Graphics.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Graphics.h	Tue Jul 14 11:34:15 2015 +0000
@@ -0,0 +1,31 @@
+
+#ifndef GRAPHICS_H
+#define GRAPHICS_H
+
+class Graphics {
+public:
+
+	Graphics(uint16_t *pFrmBuf, uint16_t dispWidth, uint16_t dispHeight);
+
+	void setFrameBuffer( uint16_t *pFrmBuf );
+	void put_line(int32_t x1, int32_t y1, int32_t x2, int32_t y2, int16_t color);
+    void put_circle( int32_t cx, int32_t cy, int16_t color, int32_t radius, int32_t Filled );
+    void put_dot( int32_t cx, int32_t cy, int16_t color );
+
+protected:
+	uint16_t windowX;
+	uint16_t windowY;
+	uint16_t *pFrmBuf;
+	
+    int32_t abs(int32_t v1) const;
+    
+    virtual void plot4points( int32_t cx, int32_t cy, int32_t x, int32_t y, int16_t color, int32_t Filled );
+    void plot8points( int32_t cx, int32_t cy, int32_t x, int32_t y, int16_t color, int32_t Filled );
+    
+};
+
+#endif
+
+
+
+
diff -r 000000000000 -r 7f5765fcd048 MyWindow.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MyWindow.cpp	Tue Jul 14 11:34:15 2015 +0000
@@ -0,0 +1,97 @@
+#include "mbed.h"
+
+#include "MyWindow.h"
+#include "EwPainter.h"
+
+MyWindow::MyWindow(EwWindow* parent) :
+    EwWindow(5, 2, 300, 250, parent),
+    _changeBtn(130, 200, 40, 20, this),
+    _checkBox(0, 0, 80, 25, this),
+    _dropDownLst(0, 0, 100, 50, this){
+
+    _changeBtn.setText("Click");
+    _changeBtn.setClickedListener(this, &MyWindow::clickListener);
+
+    _checkBox.setText("CheckBox");
+    _checkBox.setChangedListener(this, &MyWindow::checkedListener);
+
+    _dropDownLst.addString("First");
+    _dropDownLst.addString("Second");
+    _dropDownLst.addString("Third");
+
+    _clickCnt = 0;
+    _pressed = false;
+    _pressX = 0;
+    _pressY = 0;
+
+    resizeTo(parent->getWidth()-15, parent->getHeight()-35);
+    _changeBtn.moveTo(getWidth()/2-_changeBtn.getWidth()/2,
+            getHeight()-_changeBtn.getHeight()-5);
+
+    _checkBox.moveTo(5, 35);
+
+    _dropDownLst.move(getWidth()-_dropDownLst.getWidth()-5, 5);
+}
+
+bool MyWindow::paintEvent() {
+    char buf[30];
+    EwPainter painter;
+
+    painter.setBackgroundColor(EW_LIGHTGRAY);
+    painter.clear();
+
+    if (_clickCnt > 0) {
+        painter.setColor(EW_BLUE);
+        if (_clickCnt == 1) {
+            sprintf(buf, "Clicked %d time", _clickCnt);
+        }
+        else {
+            sprintf(buf, "Clicked %d times", _clickCnt);
+        }
+        painter.drawStringClearEOL(buf, 5, 5);
+    }
+
+    if (_pressed) {
+        painter.setColor(GUI_DARKRED);
+        sprintf(buf, "Touch at %d,%d", _pressX, _pressY);
+        painter.drawStringClearEOL(buf, 5, 15);
+    }
+
+    return true;
+}
+
+bool MyWindow::touchEvent(int x, int y, EwTouchState_t state) {
+
+    if (state == TouchStatePressed) {
+        _pressed = true;
+        _pressX = x;
+        _pressY = y;
+    }
+    else {
+        _pressed = false;
+    }
+
+    invalidate();
+
+    return true;
+}
+
+void MyWindow::clickListener(EwWindow* w) {
+    _clickCnt++;
+    invalidate();
+}
+
+void MyWindow::checkedListener(EwWindow* w) {
+    EwCheckBox* b = (EwCheckBox*)w;
+
+    ewCheckBoxState_t state = b->getState();
+
+    if (state == CheckBoxStateUnchecked) {
+        b->setText("Unchecked");
+    }
+    else {
+        b->setText("Checked");
+    }
+
+}
+
diff -r 000000000000 -r 7f5765fcd048 MyWindow.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MyWindow.h	Tue Jul 14 11:34:15 2015 +0000
@@ -0,0 +1,37 @@
+
+#ifndef MYWINDOW_H
+#define MYWINDOW_H
+
+#include "EwWindow.h"
+#include "EwButton.h"
+#include "EwCheckBox.h"
+#include "EwDropDown.h"
+
+class MyWindow : public EwWindow {
+public:
+
+    MyWindow(EwWindow* parent);
+
+    virtual bool paintEvent();
+    virtual bool touchEvent(int x, int y, EwTouchState_t state);
+
+    virtual bool resizedEvent() {printf("MyWindow resized\n"); return true;}
+
+
+private:
+
+    int _clickCnt;
+    bool _pressed;
+    int _pressX;
+    int _pressY;
+    EwButton _changeBtn;
+    EwCheckBox _checkBox;
+    EwDropDown _dropDownLst;
+
+
+    void clickListener(EwWindow* w);
+    void checkedListener(EwWindow* w);
+};
+
+#endif
+
diff -r 000000000000 -r 7f5765fcd048 ewgui.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ewgui.lib	Tue Jul 14 11:34:15 2015 +0000
@@ -0,0 +1,1 @@
+https://mbed.org/users/embeddedartists/code/ewgui/#0b16165ada7c
diff -r 000000000000 -r 7f5765fcd048 main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Tue Jul 14 11:34:15 2015 +0000
@@ -0,0 +1,92 @@
+
+/******************************************************************************
+ * Includes
+ *****************************************************************************/
+
+#include "mbed.h"
+
+#include "sdram.h"
+
+#include "EwGuiImpl.h"
+#include "EwFrameWindow.h"
+#include "MyWindow.h"
+
+
+/******************************************************************************
+ * Typedefs and defines
+ *****************************************************************************/
+
+
+/******************************************************************************
+ * Local variables
+ *****************************************************************************/
+
+static EwGuiImpl* gui = NULL;
+
+/******************************************************************************
+ * Local functions
+ *****************************************************************************/
+
+static void pollTouch() {
+    if (gui == NULL) return;
+
+    gui->execTouch();
+}
+
+/******************************************************************************
+ * Main function
+ *****************************************************************************/
+
+int main (void) {
+    Ticker ticker;
+
+    // Frame buffer is put in SDRAM
+    if (sdram_init() == 1) {
+        printf("Failed to initialize SDRAM\n");
+        return 1;
+    }
+
+    // instantiate and initialize GUI
+    gui = new EwGuiImpl(EwGuiImpl::TFT_4_3);
+    //gui = new EwGuiImpl(EwGuiImpl::TFT_5);
+    if (gui == NULL) {
+        printf("Failed to instantiate EwGuiImpl\n");
+        return 1;
+    }
+
+    // calibrate touch screen
+    gui->calibrate();
+
+    // register a callback that will check for touch events
+    ticker.attach(&pollTouch, 0.10);
+
+    // showing how to enable skinning
+    BUTTON_SetDefaultSkin   (BUTTON_SKIN_FLEX);
+    CHECKBOX_SetDefaultSkin (CHECKBOX_SKIN_FLEX);
+    DROPDOWN_SetDefaultSkin (DROPDOWN_SKIN_FLEX);
+    FRAMEWIN_SetDefaultSkin (FRAMEWIN_SKIN_FLEX);
+
+    // make sure the desktop has a color so that it is redrawn
+    EwWindow::setDesktopColor(EW_BLACK);
+
+    // create a frame window
+    EwFrameWindow frameWin(30, 30, gui->getDisplayWidth()-60,
+            gui->getDisplayHeight()-60, "Window Title");
+    frameWin.setTitleHeight(20);
+
+    // create and associate a custom window with the frame window
+    MyWindow myWindow(&frameWin);
+
+    // application loop running the UI and checking for touch events
+    while(1) {
+
+        // In this example touch events are checked by interrupt
+        // (pollTouch function), but we could also have done it
+        // in this while loop
+        //gui.execTouch();
+        gui->exec();
+
+    }
+
+}
+
diff -r 000000000000 -r 7f5765fcd048 mbed.bld
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Tue Jul 14 11:34:15 2015 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/da0ca467f8b5
\ No newline at end of file