Graphical demo for the LPC4088 Experiment Base Board with one of the Display Expansion Kits. This program displays how to write text in different fonts.

Dependencies:   EALib mbed

Committer:
embeddedartists
Date:
Thu Jun 25 10:30:15 2015 +0000
Revision:
0:5e5e9ec91fc8
First version

Who changed what in which revision?

UserRevisionLine numberNew contents of line
embeddedartists 0:5e5e9ec91fc8 1 /*
embeddedartists 0:5e5e9ec91fc8 2 * Copyright 2013 Embedded Artists AB
embeddedartists 0:5e5e9ec91fc8 3 *
embeddedartists 0:5e5e9ec91fc8 4 * Licensed under the Apache License, Version 2.0 (the "License");
embeddedartists 0:5e5e9ec91fc8 5 * you may not use this file except in compliance with the License.
embeddedartists 0:5e5e9ec91fc8 6 * You may obtain a copy of the License at
embeddedartists 0:5e5e9ec91fc8 7 *
embeddedartists 0:5e5e9ec91fc8 8 * http://www.apache.org/licenses/LICENSE-2.0
embeddedartists 0:5e5e9ec91fc8 9 *
embeddedartists 0:5e5e9ec91fc8 10 * Unless required by applicable law or agreed to in writing, software
embeddedartists 0:5e5e9ec91fc8 11 * distributed under the License is distributed on an "AS IS" BASIS,
embeddedartists 0:5e5e9ec91fc8 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
embeddedartists 0:5e5e9ec91fc8 13 * See the License for the specific language governing permissions and
embeddedartists 0:5e5e9ec91fc8 14 * limitations under the License.
embeddedartists 0:5e5e9ec91fc8 15 */
embeddedartists 0:5e5e9ec91fc8 16
embeddedartists 0:5e5e9ec91fc8 17 /******************************************************************************
embeddedartists 0:5e5e9ec91fc8 18 * Includes
embeddedartists 0:5e5e9ec91fc8 19 *****************************************************************************/
embeddedartists 0:5e5e9ec91fc8 20
embeddedartists 0:5e5e9ec91fc8 21 #include "mbed.h"
embeddedartists 0:5e5e9ec91fc8 22 #include "TestDisplay.h"
embeddedartists 0:5e5e9ec91fc8 23 #include "sdram.h"
embeddedartists 0:5e5e9ec91fc8 24
embeddedartists 0:5e5e9ec91fc8 25 #include "TextDemo.h"
embeddedartists 0:5e5e9ec91fc8 26
embeddedartists 0:5e5e9ec91fc8 27 /******************************************************************************
embeddedartists 0:5e5e9ec91fc8 28 * Defines and typedefs
embeddedartists 0:5e5e9ec91fc8 29 *****************************************************************************/
embeddedartists 0:5e5e9ec91fc8 30
embeddedartists 0:5e5e9ec91fc8 31 #define LCD_CONFIGURATION_43 \
embeddedartists 0:5e5e9ec91fc8 32 40, /* horizontalBackPorch */ \
embeddedartists 0:5e5e9ec91fc8 33 5, /* horizontalFrontPorch */ \
embeddedartists 0:5e5e9ec91fc8 34 2, /* hsync */ \
embeddedartists 0:5e5e9ec91fc8 35 480, /* width */ \
embeddedartists 0:5e5e9ec91fc8 36 8, /* verticalBackPorch */ \
embeddedartists 0:5e5e9ec91fc8 37 8, /* verticalFrontPorch */ \
embeddedartists 0:5e5e9ec91fc8 38 2, /* vsync */ \
embeddedartists 0:5e5e9ec91fc8 39 272, /* height */ \
embeddedartists 0:5e5e9ec91fc8 40 false, /* invertOutputEnable */ \
embeddedartists 0:5e5e9ec91fc8 41 false, /* invertPanelClock */ \
embeddedartists 0:5e5e9ec91fc8 42 true, /* invertHsync */ \
embeddedartists 0:5e5e9ec91fc8 43 true, /* invertVsync */ \
embeddedartists 0:5e5e9ec91fc8 44 1, /* acBias */ \
embeddedartists 0:5e5e9ec91fc8 45 LcdController::Bpp_16_565, /* bpp */ \
embeddedartists 0:5e5e9ec91fc8 46 9000000, /* optimalClock */ \
embeddedartists 0:5e5e9ec91fc8 47 LcdController::Tft, /* panelType */ \
embeddedartists 0:5e5e9ec91fc8 48 false /* dualPanel */
embeddedartists 0:5e5e9ec91fc8 49
embeddedartists 0:5e5e9ec91fc8 50 #define LCD_INIT_STRING_43 (char*)"v1,cd0,c50,cc0,c30,d100,c31,d100,cd1,d10,o,c51,cc100"
embeddedartists 0:5e5e9ec91fc8 51
embeddedartists 0:5e5e9ec91fc8 52 #define LCD_CONFIGURATION_50 \
embeddedartists 0:5e5e9ec91fc8 53 46, /* horizontalBackPorch */ \
embeddedartists 0:5e5e9ec91fc8 54 20, /* horizontalFrontPorch */ \
embeddedartists 0:5e5e9ec91fc8 55 2, /* hsync */ \
embeddedartists 0:5e5e9ec91fc8 56 800, /* width */ \
embeddedartists 0:5e5e9ec91fc8 57 23, /* verticalBackPorch */ \
embeddedartists 0:5e5e9ec91fc8 58 10, /* verticalFrontPorch */ \
embeddedartists 0:5e5e9ec91fc8 59 3, /* vsync */ \
embeddedartists 0:5e5e9ec91fc8 60 480, /* height */ \
embeddedartists 0:5e5e9ec91fc8 61 false, /* invertOutputEnable */ \
embeddedartists 0:5e5e9ec91fc8 62 false, /* invertPanelClock */ \
embeddedartists 0:5e5e9ec91fc8 63 true, /* invertHsync */ \
embeddedartists 0:5e5e9ec91fc8 64 true, /* invertVsync */ \
embeddedartists 0:5e5e9ec91fc8 65 1, /* acBias */ \
embeddedartists 0:5e5e9ec91fc8 66 LcdController::Bpp_16_565, /* bpp */ \
embeddedartists 0:5e5e9ec91fc8 67 30000000, /* optimalClock */ \
embeddedartists 0:5e5e9ec91fc8 68 LcdController::Tft, /* panelType */ \
embeddedartists 0:5e5e9ec91fc8 69 false /* dualPanel */
embeddedartists 0:5e5e9ec91fc8 70
embeddedartists 0:5e5e9ec91fc8 71 #define LCD_INIT_STRING_50 (char*)"v1,cc0,c31,d50,o,d200,c51,cc100"
embeddedartists 0:5e5e9ec91fc8 72
embeddedartists 0:5e5e9ec91fc8 73 #define MY_ABS(__a) (((__a) < 0) ? -(__a) : (__a))
embeddedartists 0:5e5e9ec91fc8 74
embeddedartists 0:5e5e9ec91fc8 75 /******************************************************************************
embeddedartists 0:5e5e9ec91fc8 76 * Public Functions
embeddedartists 0:5e5e9ec91fc8 77 *****************************************************************************/
embeddedartists 0:5e5e9ec91fc8 78
embeddedartists 0:5e5e9ec91fc8 79 /*
embeddedartists 0:5e5e9ec91fc8 80 Prerequisites:
embeddedartists 0:5e5e9ec91fc8 81
embeddedartists 0:5e5e9ec91fc8 82 - A display must be connected to the LPC4088 Experiment Base Board
embeddedartists 0:5e5e9ec91fc8 83 with the FPC connector
embeddedartists 0:5e5e9ec91fc8 84
embeddedartists 0:5e5e9ec91fc8 85 - The touch controller uses the I2C bus so for this test to work
embeddedartists 0:5e5e9ec91fc8 86 jumpers JP8 and JP9 on the LPC4088 Experiment Base Board must
embeddedartists 0:5e5e9ec91fc8 87 both be in positions 1-2
embeddedartists 0:5e5e9ec91fc8 88
embeddedartists 0:5e5e9ec91fc8 89 */
embeddedartists 0:5e5e9ec91fc8 90
embeddedartists 0:5e5e9ec91fc8 91 TestDisplay::TestDisplay(WhichDisplay which) :
embeddedartists 0:5e5e9ec91fc8 92 _initStr(NULL),
embeddedartists 0:5e5e9ec91fc8 93 _lcdCfg(NULL),
embeddedartists 0:5e5e9ec91fc8 94 _lcdBoard(P0_27, P0_28),
embeddedartists 0:5e5e9ec91fc8 95 _touch(P0_27, P0_28, P2_25) {
embeddedartists 0:5e5e9ec91fc8 96
embeddedartists 0:5e5e9ec91fc8 97 switch (which) {
embeddedartists 0:5e5e9ec91fc8 98 case TFT_5:
embeddedartists 0:5e5e9ec91fc8 99 _lcdCfg = new LcdController::Config(LCD_CONFIGURATION_50);
embeddedartists 0:5e5e9ec91fc8 100 _initStr = LCD_INIT_STRING_50;
embeddedartists 0:5e5e9ec91fc8 101 break;
embeddedartists 0:5e5e9ec91fc8 102 case TFT_4_3:
embeddedartists 0:5e5e9ec91fc8 103 _lcdCfg = new LcdController::Config(LCD_CONFIGURATION_43);
embeddedartists 0:5e5e9ec91fc8 104 _initStr = LCD_INIT_STRING_43;
embeddedartists 0:5e5e9ec91fc8 105 break;
embeddedartists 0:5e5e9ec91fc8 106 default:
embeddedartists 0:5e5e9ec91fc8 107 mbed_die();
embeddedartists 0:5e5e9ec91fc8 108 }
embeddedartists 0:5e5e9ec91fc8 109
embeddedartists 0:5e5e9ec91fc8 110 if (sdram_init() == 1) {
embeddedartists 0:5e5e9ec91fc8 111 printf("Failed to initialize SDRAM\n");
embeddedartists 0:5e5e9ec91fc8 112 _framebuffer = 0;
embeddedartists 0:5e5e9ec91fc8 113 } else {
embeddedartists 0:5e5e9ec91fc8 114 _framebuffer = (uint32_t) malloc(_lcdCfg->width * _lcdCfg->height * 2 * 3); // 2 is for 16 bit color, 3 is the number of buffers
embeddedartists 0:5e5e9ec91fc8 115 if (_framebuffer != 0) {
embeddedartists 0:5e5e9ec91fc8 116 memset((uint8_t*)_framebuffer, 0, _lcdCfg->width * _lcdCfg->height * 2 * 3);
embeddedartists 0:5e5e9ec91fc8 117 }
embeddedartists 0:5e5e9ec91fc8 118 }
embeddedartists 0:5e5e9ec91fc8 119 }
embeddedartists 0:5e5e9ec91fc8 120
embeddedartists 0:5e5e9ec91fc8 121 TestDisplay::~TestDisplay() {
embeddedartists 0:5e5e9ec91fc8 122 if (_framebuffer != 0) {
embeddedartists 0:5e5e9ec91fc8 123 free((void*)_framebuffer);
embeddedartists 0:5e5e9ec91fc8 124 _framebuffer = 0;
embeddedartists 0:5e5e9ec91fc8 125 }
embeddedartists 0:5e5e9ec91fc8 126 }
embeddedartists 0:5e5e9ec91fc8 127
embeddedartists 0:5e5e9ec91fc8 128 bool TestDisplay::runTest() {
embeddedartists 0:5e5e9ec91fc8 129 do {
embeddedartists 0:5e5e9ec91fc8 130 if (_framebuffer == 0) {
embeddedartists 0:5e5e9ec91fc8 131 printf("Failed to allocate memory for framebuffer\n");
embeddedartists 0:5e5e9ec91fc8 132 break;
embeddedartists 0:5e5e9ec91fc8 133 }
embeddedartists 0:5e5e9ec91fc8 134
embeddedartists 0:5e5e9ec91fc8 135 EaLcdBoard::Result result = _lcdBoard.open(_lcdCfg, _initStr);
embeddedartists 0:5e5e9ec91fc8 136 if (result != EaLcdBoard::Ok) {
embeddedartists 0:5e5e9ec91fc8 137 printf("Failed to open display, error %d\n", result);
embeddedartists 0:5e5e9ec91fc8 138 break;
embeddedartists 0:5e5e9ec91fc8 139 }
embeddedartists 0:5e5e9ec91fc8 140
embeddedartists 0:5e5e9ec91fc8 141 result = _lcdBoard.setFrameBuffer(_framebuffer);
embeddedartists 0:5e5e9ec91fc8 142 if (result != EaLcdBoard::Ok) {
embeddedartists 0:5e5e9ec91fc8 143 printf("Failed to set framebuffer, error %d\n", result);
embeddedartists 0:5e5e9ec91fc8 144 break;
embeddedartists 0:5e5e9ec91fc8 145 }
embeddedartists 0:5e5e9ec91fc8 146
embeddedartists 0:5e5e9ec91fc8 147 TextDemo textDemo((uint8_t *)_framebuffer, _lcdCfg->width, _lcdCfg->height);
embeddedartists 0:5e5e9ec91fc8 148 while (1) {
embeddedartists 0:5e5e9ec91fc8 149 textDemo.run(_lcdBoard, 750, 20);
embeddedartists 0:5e5e9ec91fc8 150 }
embeddedartists 0:5e5e9ec91fc8 151 } while(0);
embeddedartists 0:5e5e9ec91fc8 152
embeddedartists 0:5e5e9ec91fc8 153 return false;
embeddedartists 0:5e5e9ec91fc8 154 }
embeddedartists 0:5e5e9ec91fc8 155
embeddedartists 0:5e5e9ec91fc8 156 void TestDisplay::calibrate_drawMarker(Graphics &g, uint16_t x, uint16_t y, bool erase) {
embeddedartists 0:5e5e9ec91fc8 157 uint16_t color = (erase ? 0x0000 : 0xffff);
embeddedartists 0:5e5e9ec91fc8 158 g.put_line(x-15, y, x+15, y, color);
embeddedartists 0:5e5e9ec91fc8 159 g.put_line(x, y-15, x, y+15, color);
embeddedartists 0:5e5e9ec91fc8 160 g.put_circle(x, y, color, 10, false);
embeddedartists 0:5e5e9ec91fc8 161 }
embeddedartists 0:5e5e9ec91fc8 162
embeddedartists 0:5e5e9ec91fc8 163 bool TestDisplay::calibrate_display() {
embeddedartists 0:5e5e9ec91fc8 164 bool morePoints = true;
embeddedartists 0:5e5e9ec91fc8 165 uint16_t x, y;
embeddedartists 0:5e5e9ec91fc8 166 int point = 0;
embeddedartists 0:5e5e9ec91fc8 167 Graphics g((uint16_t*)_framebuffer, _lcdCfg->width, _lcdCfg->height);
embeddedartists 0:5e5e9ec91fc8 168
embeddedartists 0:5e5e9ec91fc8 169 do {
embeddedartists 0:5e5e9ec91fc8 170 if (!_touch.init(_lcdCfg->width, _lcdCfg->height)) {
embeddedartists 0:5e5e9ec91fc8 171 printf("Failed to initialize touch controller\n");
embeddedartists 0:5e5e9ec91fc8 172 break;
embeddedartists 0:5e5e9ec91fc8 173 }
embeddedartists 0:5e5e9ec91fc8 174 if (!_touch.calibrateStart()) {
embeddedartists 0:5e5e9ec91fc8 175 printf("Failed to start calibration\n");
embeddedartists 0:5e5e9ec91fc8 176 break;
embeddedartists 0:5e5e9ec91fc8 177 }
embeddedartists 0:5e5e9ec91fc8 178 while (morePoints) {
embeddedartists 0:5e5e9ec91fc8 179 if (point++ > 0) {
embeddedartists 0:5e5e9ec91fc8 180 // erase old location
embeddedartists 0:5e5e9ec91fc8 181 calibrate_drawMarker(g, x, y, true);
embeddedartists 0:5e5e9ec91fc8 182 }
embeddedartists 0:5e5e9ec91fc8 183 if (!_touch.getNextCalibratePoint(&x, &y)) {
embeddedartists 0:5e5e9ec91fc8 184 printf("Failed to get calibration point\n");
embeddedartists 0:5e5e9ec91fc8 185 break;
embeddedartists 0:5e5e9ec91fc8 186 }
embeddedartists 0:5e5e9ec91fc8 187 calibrate_drawMarker(g, x, y, false);
embeddedartists 0:5e5e9ec91fc8 188 if (!_touch.waitForCalibratePoint(&morePoints, 0)) {
embeddedartists 0:5e5e9ec91fc8 189 printf("Failed to get user click\n");
embeddedartists 0:5e5e9ec91fc8 190 break;
embeddedartists 0:5e5e9ec91fc8 191 }
embeddedartists 0:5e5e9ec91fc8 192 }
embeddedartists 0:5e5e9ec91fc8 193 if (morePoints) {
embeddedartists 0:5e5e9ec91fc8 194 // aborted calibration due to error(s)
embeddedartists 0:5e5e9ec91fc8 195 break;
embeddedartists 0:5e5e9ec91fc8 196 }
embeddedartists 0:5e5e9ec91fc8 197
embeddedartists 0:5e5e9ec91fc8 198 // erase old location
embeddedartists 0:5e5e9ec91fc8 199 calibrate_drawMarker(g, x, y, true);
embeddedartists 0:5e5e9ec91fc8 200
embeddedartists 0:5e5e9ec91fc8 201 // allow user to draw for 5999 seconds
embeddedartists 0:5e5e9ec91fc8 202 Timer t;
embeddedartists 0:5e5e9ec91fc8 203 t.start();
embeddedartists 0:5e5e9ec91fc8 204 TouchPanel::touchCoordinate_t tc;
embeddedartists 0:5e5e9ec91fc8 205 while(t.read() < 6000) {
embeddedartists 0:5e5e9ec91fc8 206 if (_touch.read(tc)) {
embeddedartists 0:5e5e9ec91fc8 207 //printf("TC: x,y,z = {%5d, %5d, %5d}\n", tc.x, tc.y, tc.z);
embeddedartists 0:5e5e9ec91fc8 208 if (tc.z) {
embeddedartists 0:5e5e9ec91fc8 209 g.put_dot(tc.x, tc.y, 0xffff);
embeddedartists 0:5e5e9ec91fc8 210 }
embeddedartists 0:5e5e9ec91fc8 211 }
embeddedartists 0:5e5e9ec91fc8 212 }
embeddedartists 0:5e5e9ec91fc8 213 } while(0);
embeddedartists 0:5e5e9ec91fc8 214
embeddedartists 0:5e5e9ec91fc8 215 return !morePoints;
embeddedartists 0:5e5e9ec91fc8 216 }