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@0:7f5765fcd048, 2015-07-14 (annotated)
- Committer:
- embeddedartists
- Date:
- Tue Jul 14 11:34:15 2015 +0000
- Revision:
- 0:7f5765fcd048
First version
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
embeddedartists | 0:7f5765fcd048 | 1 | #include "EwGuiImpl.h" |
embeddedartists | 0:7f5765fcd048 | 2 | |
embeddedartists | 0:7f5765fcd048 | 3 | #include "LcdController.h" |
embeddedartists | 0:7f5765fcd048 | 4 | #include "EaLcdBoardGPIO.h" |
embeddedartists | 0:7f5765fcd048 | 5 | #include "sdram.h" |
embeddedartists | 0:7f5765fcd048 | 6 | #include "AR1021I2C.h" |
embeddedartists | 0:7f5765fcd048 | 7 | |
embeddedartists | 0:7f5765fcd048 | 8 | |
embeddedartists | 0:7f5765fcd048 | 9 | #define PIXEL_SIZE (2) |
embeddedartists | 0:7f5765fcd048 | 10 | |
embeddedartists | 0:7f5765fcd048 | 11 | #define LCD_CONFIGURATION_43 \ |
embeddedartists | 0:7f5765fcd048 | 12 | 40, /* horizontalBackPorch */ \ |
embeddedartists | 0:7f5765fcd048 | 13 | 5, /* horizontalFrontPorch */ \ |
embeddedartists | 0:7f5765fcd048 | 14 | 2, /* hsync */ \ |
embeddedartists | 0:7f5765fcd048 | 15 | 480, /* width */ \ |
embeddedartists | 0:7f5765fcd048 | 16 | 8, /* verticalBackPorch */ \ |
embeddedartists | 0:7f5765fcd048 | 17 | 8, /* verticalFrontPorch */ \ |
embeddedartists | 0:7f5765fcd048 | 18 | 2, /* vsync */ \ |
embeddedartists | 0:7f5765fcd048 | 19 | 272, /* height */ \ |
embeddedartists | 0:7f5765fcd048 | 20 | false, /* invertOutputEnable */ \ |
embeddedartists | 0:7f5765fcd048 | 21 | false, /* invertPanelClock */ \ |
embeddedartists | 0:7f5765fcd048 | 22 | true, /* invertHsync */ \ |
embeddedartists | 0:7f5765fcd048 | 23 | true, /* invertVsync */ \ |
embeddedartists | 0:7f5765fcd048 | 24 | 1, /* acBias */ \ |
embeddedartists | 0:7f5765fcd048 | 25 | LcdController::Bpp_16_565, /* bpp */ \ |
embeddedartists | 0:7f5765fcd048 | 26 | 9000000, /* optimalClock */ \ |
embeddedartists | 0:7f5765fcd048 | 27 | LcdController::Tft, /* panelType */ \ |
embeddedartists | 0:7f5765fcd048 | 28 | false /* dualPanel */ |
embeddedartists | 0:7f5765fcd048 | 29 | |
embeddedartists | 0:7f5765fcd048 | 30 | #define LCD_INIT_STRING_43 (char*)"v1,cd0,c50,cc0,c30,d100,c31,d100,cd1,d10,o,c51,cc100" |
embeddedartists | 0:7f5765fcd048 | 31 | |
embeddedartists | 0:7f5765fcd048 | 32 | #define LCD_CONFIGURATION_50 \ |
embeddedartists | 0:7f5765fcd048 | 33 | 46, /* horizontalBackPorch */ \ |
embeddedartists | 0:7f5765fcd048 | 34 | 20, /* horizontalFrontPorch */ \ |
embeddedartists | 0:7f5765fcd048 | 35 | 2, /* hsync */ \ |
embeddedartists | 0:7f5765fcd048 | 36 | 800, /* width */ \ |
embeddedartists | 0:7f5765fcd048 | 37 | 23, /* verticalBackPorch */ \ |
embeddedartists | 0:7f5765fcd048 | 38 | 10, /* verticalFrontPorch */ \ |
embeddedartists | 0:7f5765fcd048 | 39 | 3, /* vsync */ \ |
embeddedartists | 0:7f5765fcd048 | 40 | 480, /* height */ \ |
embeddedartists | 0:7f5765fcd048 | 41 | false, /* invertOutputEnable */ \ |
embeddedartists | 0:7f5765fcd048 | 42 | false, /* invertPanelClock */ \ |
embeddedartists | 0:7f5765fcd048 | 43 | true, /* invertHsync */ \ |
embeddedartists | 0:7f5765fcd048 | 44 | true, /* invertVsync */ \ |
embeddedartists | 0:7f5765fcd048 | 45 | 1, /* acBias */ \ |
embeddedartists | 0:7f5765fcd048 | 46 | LcdController::Bpp_16_565, /* bpp */ \ |
embeddedartists | 0:7f5765fcd048 | 47 | 30000000, /* optimalClock */ \ |
embeddedartists | 0:7f5765fcd048 | 48 | LcdController::Tft, /* panelType */ \ |
embeddedartists | 0:7f5765fcd048 | 49 | false /* dualPanel */ |
embeddedartists | 0:7f5765fcd048 | 50 | |
embeddedartists | 0:7f5765fcd048 | 51 | #define LCD_INIT_STRING_50 (char*)"v1,cc0,c31,d50,o,d200,c51,cc100" |
embeddedartists | 0:7f5765fcd048 | 52 | |
embeddedartists | 0:7f5765fcd048 | 53 | EwGuiImpl::EwGuiImpl(WhichDisplay which) { |
embeddedartists | 0:7f5765fcd048 | 54 | |
embeddedartists | 0:7f5765fcd048 | 55 | EaLcdBoardGPIO lcdBoard(P0_27, P0_28); |
embeddedartists | 0:7f5765fcd048 | 56 | EaLcdBoardGPIO::Result result; |
embeddedartists | 0:7f5765fcd048 | 57 | LcdController::Config* lcdCfg; |
embeddedartists | 0:7f5765fcd048 | 58 | |
embeddedartists | 0:7f5765fcd048 | 59 | do { |
embeddedartists | 0:7f5765fcd048 | 60 | |
embeddedartists | 0:7f5765fcd048 | 61 | switch (which) { |
embeddedartists | 0:7f5765fcd048 | 62 | case TFT_5: |
embeddedartists | 0:7f5765fcd048 | 63 | lcdCfg = new LcdController::Config(LCD_CONFIGURATION_50); |
embeddedartists | 0:7f5765fcd048 | 64 | result = lcdBoard.open(lcdCfg, LCD_INIT_STRING_50); |
embeddedartists | 0:7f5765fcd048 | 65 | break; |
embeddedartists | 0:7f5765fcd048 | 66 | case TFT_4_3: |
embeddedartists | 0:7f5765fcd048 | 67 | lcdCfg = new LcdController::Config(LCD_CONFIGURATION_43); |
embeddedartists | 0:7f5765fcd048 | 68 | result = lcdBoard.open(lcdCfg, LCD_INIT_STRING_43); |
embeddedartists | 0:7f5765fcd048 | 69 | break; |
embeddedartists | 0:7f5765fcd048 | 70 | default: |
embeddedartists | 0:7f5765fcd048 | 71 | mbed_die(); |
embeddedartists | 0:7f5765fcd048 | 72 | } |
embeddedartists | 0:7f5765fcd048 | 73 | |
embeddedartists | 0:7f5765fcd048 | 74 | if (result != EaLcdBoard::Ok) { |
embeddedartists | 0:7f5765fcd048 | 75 | printf("Failed to open display: %d\n", result); |
embeddedartists | 0:7f5765fcd048 | 76 | break; |
embeddedartists | 0:7f5765fcd048 | 77 | } |
embeddedartists | 0:7f5765fcd048 | 78 | |
embeddedartists | 0:7f5765fcd048 | 79 | _width = lcdCfg->width; |
embeddedartists | 0:7f5765fcd048 | 80 | _height = lcdCfg->height; |
embeddedartists | 0:7f5765fcd048 | 81 | |
embeddedartists | 0:7f5765fcd048 | 82 | // allocate buffer, width x height x 2 (2 bytes = 16 bit color data) |
embeddedartists | 0:7f5765fcd048 | 83 | _fb = (uint32_t)malloc(_width*_height*PIXEL_SIZE); |
embeddedartists | 0:7f5765fcd048 | 84 | if (_fb == 0) { |
embeddedartists | 0:7f5765fcd048 | 85 | printf("Failed to allocate frame buffer\n"); |
embeddedartists | 0:7f5765fcd048 | 86 | break; |
embeddedartists | 0:7f5765fcd048 | 87 | } |
embeddedartists | 0:7f5765fcd048 | 88 | |
embeddedartists | 0:7f5765fcd048 | 89 | result = lcdBoard.setFrameBuffer(_fb); |
embeddedartists | 0:7f5765fcd048 | 90 | if (result != EaLcdBoard::Ok) { |
embeddedartists | 0:7f5765fcd048 | 91 | printf("Failed to activate frameBuffer: %d\n", result); |
embeddedartists | 0:7f5765fcd048 | 92 | break; |
embeddedartists | 0:7f5765fcd048 | 93 | } |
embeddedartists | 0:7f5765fcd048 | 94 | |
embeddedartists | 0:7f5765fcd048 | 95 | _memSz = 1024*1024*5; |
embeddedartists | 0:7f5765fcd048 | 96 | _mem = (uint32_t)malloc(_memSz); |
embeddedartists | 0:7f5765fcd048 | 97 | if (_mem == 0) { |
embeddedartists | 0:7f5765fcd048 | 98 | printf("Failed to allocate memory block for emwin\n"); |
embeddedartists | 0:7f5765fcd048 | 99 | break; |
embeddedartists | 0:7f5765fcd048 | 100 | } |
embeddedartists | 0:7f5765fcd048 | 101 | |
embeddedartists | 0:7f5765fcd048 | 102 | |
embeddedartists | 0:7f5765fcd048 | 103 | memset((void*)_fb, 0x0, _width*_height*PIXEL_SIZE); |
embeddedartists | 0:7f5765fcd048 | 104 | |
embeddedartists | 0:7f5765fcd048 | 105 | // create touch panel |
embeddedartists | 0:7f5765fcd048 | 106 | _touch = new AR1021I2C(P0_27, P0_28, P2_25); |
embeddedartists | 0:7f5765fcd048 | 107 | |
embeddedartists | 0:7f5765fcd048 | 108 | if (!_touch->init(_width, _height)) { |
embeddedartists | 0:7f5765fcd048 | 109 | printf("TouchPanel.init failed\n"); |
embeddedartists | 0:7f5765fcd048 | 110 | break; |
embeddedartists | 0:7f5765fcd048 | 111 | } |
embeddedartists | 0:7f5765fcd048 | 112 | |
embeddedartists | 0:7f5765fcd048 | 113 | init(); |
embeddedartists | 0:7f5765fcd048 | 114 | |
embeddedartists | 0:7f5765fcd048 | 115 | } while(0); |
embeddedartists | 0:7f5765fcd048 | 116 | |
embeddedartists | 0:7f5765fcd048 | 117 | |
embeddedartists | 0:7f5765fcd048 | 118 | } |
embeddedartists | 0:7f5765fcd048 | 119 | |
embeddedartists | 0:7f5765fcd048 | 120 | void* EwGuiImpl::getMemoryBlockAddress() { |
embeddedartists | 0:7f5765fcd048 | 121 | return (void*)_mem; |
embeddedartists | 0:7f5765fcd048 | 122 | } |
embeddedartists | 0:7f5765fcd048 | 123 | |
embeddedartists | 0:7f5765fcd048 | 124 | uint32_t EwGuiImpl::getMemoryBlockSize() { |
embeddedartists | 0:7f5765fcd048 | 125 | return _memSz; |
embeddedartists | 0:7f5765fcd048 | 126 | } |
embeddedartists | 0:7f5765fcd048 | 127 | |
embeddedartists | 0:7f5765fcd048 | 128 | uint32_t EwGuiImpl::getDisplayWidth() { |
embeddedartists | 0:7f5765fcd048 | 129 | return _width; |
embeddedartists | 0:7f5765fcd048 | 130 | } |
embeddedartists | 0:7f5765fcd048 | 131 | |
embeddedartists | 0:7f5765fcd048 | 132 | uint32_t EwGuiImpl::getDisplayHeight() { |
embeddedartists | 0:7f5765fcd048 | 133 | return _height; |
embeddedartists | 0:7f5765fcd048 | 134 | } |
embeddedartists | 0:7f5765fcd048 | 135 | |
embeddedartists | 0:7f5765fcd048 | 136 | void* EwGuiImpl::getFrameBufferAddress() { |
embeddedartists | 0:7f5765fcd048 | 137 | return (void*)_fb; |
embeddedartists | 0:7f5765fcd048 | 138 | } |
embeddedartists | 0:7f5765fcd048 | 139 | |
embeddedartists | 0:7f5765fcd048 | 140 | void EwGuiImpl::getTouchValues(int32_t* x, int32_t* y, int32_t* z) { |
embeddedartists | 0:7f5765fcd048 | 141 | |
embeddedartists | 0:7f5765fcd048 | 142 | if (!x || !y || !z) return; |
embeddedartists | 0:7f5765fcd048 | 143 | |
embeddedartists | 0:7f5765fcd048 | 144 | TouchPanel::touchCoordinate_t coord; |
embeddedartists | 0:7f5765fcd048 | 145 | _touch->read(coord); |
embeddedartists | 0:7f5765fcd048 | 146 | |
embeddedartists | 0:7f5765fcd048 | 147 | *x = coord.x; |
embeddedartists | 0:7f5765fcd048 | 148 | *y = coord.y; |
embeddedartists | 0:7f5765fcd048 | 149 | *z = coord.z; |
embeddedartists | 0:7f5765fcd048 | 150 | } |
embeddedartists | 0:7f5765fcd048 | 151 | |
embeddedartists | 0:7f5765fcd048 | 152 | void EwGuiImpl::calibrate() { |
embeddedartists | 0:7f5765fcd048 | 153 | |
embeddedartists | 0:7f5765fcd048 | 154 | uint16_t x = 0; |
embeddedartists | 0:7f5765fcd048 | 155 | uint16_t y = 0; |
embeddedartists | 0:7f5765fcd048 | 156 | bool hasMorePoints = false; |
embeddedartists | 0:7f5765fcd048 | 157 | |
embeddedartists | 0:7f5765fcd048 | 158 | EwPainter painter; |
embeddedartists | 0:7f5765fcd048 | 159 | painter.saveContext(); |
embeddedartists | 0:7f5765fcd048 | 160 | |
embeddedartists | 0:7f5765fcd048 | 161 | do { |
embeddedartists | 0:7f5765fcd048 | 162 | |
embeddedartists | 0:7f5765fcd048 | 163 | printf("Starting calibration\n"); |
embeddedartists | 0:7f5765fcd048 | 164 | if (!_touch->calibrateStart()) { |
embeddedartists | 0:7f5765fcd048 | 165 | printf("Failed to start calibration\n"); |
embeddedartists | 0:7f5765fcd048 | 166 | break; |
embeddedartists | 0:7f5765fcd048 | 167 | } |
embeddedartists | 0:7f5765fcd048 | 168 | |
embeddedartists | 0:7f5765fcd048 | 169 | do { |
embeddedartists | 0:7f5765fcd048 | 170 | if (!_touch->getNextCalibratePoint(&x, &y)) { |
embeddedartists | 0:7f5765fcd048 | 171 | printf("Failed to get next calibrate point\n"); |
embeddedartists | 0:7f5765fcd048 | 172 | break; |
embeddedartists | 0:7f5765fcd048 | 173 | } |
embeddedartists | 0:7f5765fcd048 | 174 | |
embeddedartists | 0:7f5765fcd048 | 175 | printf("calib: x=%d, y=%d\n", x, y); |
embeddedartists | 0:7f5765fcd048 | 176 | drawCalibPoint(painter, x, y); |
embeddedartists | 0:7f5765fcd048 | 177 | |
embeddedartists | 0:7f5765fcd048 | 178 | if (!_touch->waitForCalibratePoint(&hasMorePoints, 0)) { |
embeddedartists | 0:7f5765fcd048 | 179 | printf("Failed waiting for calibration point\n"); |
embeddedartists | 0:7f5765fcd048 | 180 | break; |
embeddedartists | 0:7f5765fcd048 | 181 | } |
embeddedartists | 0:7f5765fcd048 | 182 | |
embeddedartists | 0:7f5765fcd048 | 183 | } while(hasMorePoints); |
embeddedartists | 0:7f5765fcd048 | 184 | |
embeddedartists | 0:7f5765fcd048 | 185 | printf("Calibration done\n"); |
embeddedartists | 0:7f5765fcd048 | 186 | |
embeddedartists | 0:7f5765fcd048 | 187 | |
embeddedartists | 0:7f5765fcd048 | 188 | } while (0); |
embeddedartists | 0:7f5765fcd048 | 189 | |
embeddedartists | 0:7f5765fcd048 | 190 | |
embeddedartists | 0:7f5765fcd048 | 191 | painter.clear(); |
embeddedartists | 0:7f5765fcd048 | 192 | painter.restoreContext(); |
embeddedartists | 0:7f5765fcd048 | 193 | } |
embeddedartists | 0:7f5765fcd048 | 194 | |
embeddedartists | 0:7f5765fcd048 | 195 | void EwGuiImpl::drawCalibPoint(EwPainter &painter, int32_t x, int32_t y) { |
embeddedartists | 0:7f5765fcd048 | 196 | |
embeddedartists | 0:7f5765fcd048 | 197 | painter.clear(); |
embeddedartists | 0:7f5765fcd048 | 198 | painter.setColor(EW_WHITE); |
embeddedartists | 0:7f5765fcd048 | 199 | painter.drawStringHorizCenter("Touch circle to calibrate", |
embeddedartists | 0:7f5765fcd048 | 200 | getDisplayWidth()/2, getDisplayHeight()/2); |
embeddedartists | 0:7f5765fcd048 | 201 | |
embeddedartists | 0:7f5765fcd048 | 202 | painter.fillCircle(x, y, 10); |
embeddedartists | 0:7f5765fcd048 | 203 | painter.setColor(EW_BLACK); |
embeddedartists | 0:7f5765fcd048 | 204 | painter.fillCircle(x, y, 5); |
embeddedartists | 0:7f5765fcd048 | 205 | } |
embeddedartists | 0:7f5765fcd048 | 206 |