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.

EwGuiImpl.cpp

Committer:
embeddedartists
Date:
2015-07-14
Revision:
0:7f5765fcd048

File content as of revision 0:7f5765fcd048:

#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);
}