Production Test Program (PTP) for the LPC4088 Experiment Base Board

Dependencies:   EALib I2S LM75B SDFileSystem mbed

Committer:
embeddedartists
Date:
Wed Oct 01 11:16:38 2014 +0000
Revision:
9:eb6086159020
Parent:
7:48375cb50f3a
Updated used libraries

Who changed what in which revision?

UserRevisionLine numberNew contents of line
embeddedartists 2:2f4b7535ceb3 1 /*
embeddedartists 2:2f4b7535ceb3 2 * Copyright 2013 Embedded Artists AB
embeddedartists 2:2f4b7535ceb3 3 *
embeddedartists 2:2f4b7535ceb3 4 * Licensed under the Apache License, Version 2.0 (the "License");
embeddedartists 2:2f4b7535ceb3 5 * you may not use this file except in compliance with the License.
embeddedartists 2:2f4b7535ceb3 6 * You may obtain a copy of the License at
embeddedartists 2:2f4b7535ceb3 7 *
embeddedartists 2:2f4b7535ceb3 8 * http://www.apache.org/licenses/LICENSE-2.0
embeddedartists 2:2f4b7535ceb3 9 *
embeddedartists 2:2f4b7535ceb3 10 * Unless required by applicable law or agreed to in writing, software
embeddedartists 2:2f4b7535ceb3 11 * distributed under the License is distributed on an "AS IS" BASIS,
embeddedartists 2:2f4b7535ceb3 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
embeddedartists 2:2f4b7535ceb3 13 * See the License for the specific language governing permissions and
embeddedartists 2:2f4b7535ceb3 14 * limitations under the License.
embeddedartists 2:2f4b7535ceb3 15 */
embeddedartists 2:2f4b7535ceb3 16
embeddedartists 2:2f4b7535ceb3 17 /******************************************************************************
embeddedartists 2:2f4b7535ceb3 18 * Includes
embeddedartists 2:2f4b7535ceb3 19 *****************************************************************************/
embeddedartists 2:2f4b7535ceb3 20
embeddedartists 2:2f4b7535ceb3 21 #include "mbed.h"
embeddedartists 2:2f4b7535ceb3 22 #include "TestDisplay.h"
embeddedartists 2:2f4b7535ceb3 23 #include "sdram.h"
embeddedartists 2:2f4b7535ceb3 24
embeddedartists 2:2f4b7535ceb3 25
embeddedartists 2:2f4b7535ceb3 26 /******************************************************************************
embeddedartists 2:2f4b7535ceb3 27 * Defines and typedefs
embeddedartists 2:2f4b7535ceb3 28 *****************************************************************************/
embeddedartists 2:2f4b7535ceb3 29
embeddedartists 2:2f4b7535ceb3 30 #define LCD_CONFIGURATION \
embeddedartists 2:2f4b7535ceb3 31 40, /* horizontalBackPorch */ \
embeddedartists 2:2f4b7535ceb3 32 5, /* horizontalFrontPorch */ \
embeddedartists 2:2f4b7535ceb3 33 2, /* hsync */ \
embeddedartists 2:2f4b7535ceb3 34 480, /* width */ \
embeddedartists 2:2f4b7535ceb3 35 8, /* verticalBackPorch */ \
embeddedartists 2:2f4b7535ceb3 36 8, /* verticalFrontPorch */ \
embeddedartists 2:2f4b7535ceb3 37 2, /* vsync */ \
embeddedartists 2:2f4b7535ceb3 38 272, /* height */ \
embeddedartists 2:2f4b7535ceb3 39 false, /* invertOutputEnable */ \
embeddedartists 2:2f4b7535ceb3 40 false, /* invertPanelClock */ \
embeddedartists 2:2f4b7535ceb3 41 true, /* invertHsync */ \
embeddedartists 2:2f4b7535ceb3 42 true, /* invertVsync */ \
embeddedartists 2:2f4b7535ceb3 43 1, /* acBias */ \
embeddedartists 2:2f4b7535ceb3 44 LcdController::Bpp_16_565, /* bpp */ \
embeddedartists 2:2f4b7535ceb3 45 9000000, /* optimalClock */ \
embeddedartists 2:2f4b7535ceb3 46 LcdController::Tft, /* panelType */ \
embeddedartists 2:2f4b7535ceb3 47 false /* dualPanel */
embeddedartists 2:2f4b7535ceb3 48
embeddedartists 2:2f4b7535ceb3 49 #define LCD_INIT_STRING (char*)"v1,cd0,c50,cc0,c30,d100,c31,d100,cd1,d10,o,c51,cc100"
embeddedartists 2:2f4b7535ceb3 50
embeddedartists 2:2f4b7535ceb3 51 /******************************************************************************
embeddedartists 2:2f4b7535ceb3 52 * Public Functions
embeddedartists 2:2f4b7535ceb3 53 *****************************************************************************/
embeddedartists 2:2f4b7535ceb3 54
embeddedartists 2:2f4b7535ceb3 55 /*
embeddedartists 2:2f4b7535ceb3 56 Prerequisites:
embeddedartists 2:2f4b7535ceb3 57
embeddedartists 2:2f4b7535ceb3 58 - A display must be connected to the LPC4088 Experiment Base Board
embeddedartists 2:2f4b7535ceb3 59 with the FPC connector
embeddedartists 2:2f4b7535ceb3 60
embeddedartists 2:2f4b7535ceb3 61 - The touch controller uses the I2C bus so for this test to work
embeddedartists 2:2f4b7535ceb3 62 jumpers JP8 and JP9 on the LPC4088 Experiment Base Board must
embeddedartists 2:2f4b7535ceb3 63 both be in positions 1-2
embeddedartists 2:2f4b7535ceb3 64
embeddedartists 2:2f4b7535ceb3 65 */
embeddedartists 2:2f4b7535ceb3 66
embeddedartists 2:2f4b7535ceb3 67 /*
embeddedartists 2:2f4b7535ceb3 68 Test Description:
embeddedartists 2:2f4b7535ceb3 69
embeddedartists 2:2f4b7535ceb3 70 - The SDRAM is initialized and a framebuffer is allocated
embeddedartists 2:2f4b7535ceb3 71 - Display is initialized and a color bar (red-green-blue) is shown
embeddedartists 2:2f4b7535ceb3 72 - The user have 10 seconds to test display contrast by turning the
embeddedartists 2:2f4b7535ceb3 73 right trimpot on the board
embeddedartists 2:2f4b7535ceb3 74 - The touch calibration is started and the user must press each of
embeddedartists 2:2f4b7535ceb3 75 the four crosshairs that appear.
embeddedartists 2:2f4b7535ceb3 76 - After calibration the display can be drawn upon for 5 seconds.
embeddedartists 2:2f4b7535ceb3 77
embeddedartists 2:2f4b7535ceb3 78 Any failed part test will abort the sequence
embeddedartists 2:2f4b7535ceb3 79 */
embeddedartists 2:2f4b7535ceb3 80
embeddedartists 2:2f4b7535ceb3 81 TestDisplay::TestDisplay() :
embeddedartists 2:2f4b7535ceb3 82 _lcdCfg(LCD_CONFIGURATION),
embeddedartists 2:2f4b7535ceb3 83 _lcdBoard(P0_27, P0_28),
embeddedartists 2:2f4b7535ceb3 84 _touch(P0_27, P0_28, P2_25) {
embeddedartists 2:2f4b7535ceb3 85
embeddedartists 2:2f4b7535ceb3 86 if (sdram_init() == 1) {
embeddedartists 2:2f4b7535ceb3 87 printf("Failed to initialize SDRAM\n");
embeddedartists 2:2f4b7535ceb3 88 _framebuffer = 0;
embeddedartists 2:2f4b7535ceb3 89 } else {
embeddedartists 2:2f4b7535ceb3 90 _framebuffer = (uint32_t) malloc(_lcdCfg.width * _lcdCfg.height * 2);
embeddedartists 2:2f4b7535ceb3 91 }
embeddedartists 2:2f4b7535ceb3 92 _displayWorking = false;
embeddedartists 2:2f4b7535ceb3 93 }
embeddedartists 2:2f4b7535ceb3 94
embeddedartists 2:2f4b7535ceb3 95 TestDisplay::~TestDisplay() {
embeddedartists 2:2f4b7535ceb3 96 if (_framebuffer != 0) {
embeddedartists 2:2f4b7535ceb3 97 free((void*)_framebuffer);
embeddedartists 2:2f4b7535ceb3 98 _framebuffer = 0;
embeddedartists 2:2f4b7535ceb3 99 }
embeddedartists 2:2f4b7535ceb3 100 }
embeddedartists 2:2f4b7535ceb3 101
embeddedartists 2:2f4b7535ceb3 102 void TestDisplay::showStatus(bool success) {
embeddedartists 2:2f4b7535ceb3 103 if (_displayWorking) {
embeddedartists 2:2f4b7535ceb3 104 if (success) {
embeddedartists 2:2f4b7535ceb3 105 // Green cannot be memsetted so it will have to be the
embeddedartists 2:2f4b7535ceb3 106 // more manual way
embeddedartists 2:2f4b7535ceb3 107 uint16_t* p = (uint16_t*)_framebuffer;
embeddedartists 2:2f4b7535ceb3 108 for (int x = _lcdCfg.width; x > 0; x--) {
embeddedartists 2:2f4b7535ceb3 109 for (int y = _lcdCfg.height; y > 0; y--) {
embeddedartists 2:2f4b7535ceb3 110 *p++ = 0x07e0;
embeddedartists 2:2f4b7535ceb3 111 }
embeddedartists 2:2f4b7535ceb3 112 }
embeddedartists 2:2f4b7535ceb3 113 } else {
embeddedartists 2:2f4b7535ceb3 114 // Red is possible to set directly as 0xe0e0 in RGB565 have
embeddedartists 2:2f4b7535ceb3 115 // only significant RED bits set.
embeddedartists 2:2f4b7535ceb3 116 memset((uint8_t*)_framebuffer, 0xe0, _lcdCfg.width * _lcdCfg.height * 2); // RED
embeddedartists 2:2f4b7535ceb3 117 }
embeddedartists 2:2f4b7535ceb3 118 }
embeddedartists 2:2f4b7535ceb3 119 }
embeddedartists 2:2f4b7535ceb3 120
embeddedartists 2:2f4b7535ceb3 121 bool TestDisplay::runTest() {
embeddedartists 2:2f4b7535ceb3 122 bool testPassed = false;
embeddedartists 2:2f4b7535ceb3 123 do {
embeddedartists 2:2f4b7535ceb3 124 if (_framebuffer == 0) {
embeddedartists 2:2f4b7535ceb3 125 printf("Failed to allocate memory for framebuffer\n");
embeddedartists 2:2f4b7535ceb3 126 break;
embeddedartists 2:2f4b7535ceb3 127 }
embeddedartists 2:2f4b7535ceb3 128
embeddedartists 2:2f4b7535ceb3 129 // Prepare framebuffer
embeddedartists 2:2f4b7535ceb3 130 drawBars();
embeddedartists 2:2f4b7535ceb3 131
embeddedartists 2:2f4b7535ceb3 132 EaLcdBoard::Result result = _lcdBoard.open(&_lcdCfg, LCD_INIT_STRING);
embeddedartists 2:2f4b7535ceb3 133 if (result != EaLcdBoard::Ok) {
embeddedartists 2:2f4b7535ceb3 134 printf("Failed to open display, error %d\n", result);
embeddedartists 2:2f4b7535ceb3 135 break;
embeddedartists 2:2f4b7535ceb3 136 }
embeddedartists 2:2f4b7535ceb3 137
embeddedartists 2:2f4b7535ceb3 138 result = _lcdBoard.setFrameBuffer(_framebuffer);
embeddedartists 2:2f4b7535ceb3 139 if (result != EaLcdBoard::Ok) {
embeddedartists 2:2f4b7535ceb3 140 printf("Failed to set framebuffer, error %d\n", result);
embeddedartists 2:2f4b7535ceb3 141 break;
embeddedartists 2:2f4b7535ceb3 142 }
embeddedartists 2:2f4b7535ceb3 143
embeddedartists 2:2f4b7535ceb3 144 printf("Initialized. Control contrast with right trimpot (8 seconds)\n");
embeddedartists 2:2f4b7535ceb3 145 AnalogIn trimpot(p15);
embeddedartists 2:2f4b7535ceb3 146 Timer t;
embeddedartists 2:2f4b7535ceb3 147 t.start();
embeddedartists 2:2f4b7535ceb3 148 int delays = 0;
embeddedartists 2:2f4b7535ceb3 149 float last = -0.999;
embeddedartists 2:2f4b7535ceb3 150 while (t.read() < 8) {
embeddedartists 2:2f4b7535ceb3 151 float f = trimpot.read();
embeddedartists 2:2f4b7535ceb3 152 if (f != last) {
embeddedartists 2:2f4b7535ceb3 153 last = f;
embeddedartists 2:2f4b7535ceb3 154 _lcdBoard.setBC(100*f); // contrast is in 0..100 and analog value is 0.000..1.000
embeddedartists 2:2f4b7535ceb3 155 }
embeddedartists 2:2f4b7535ceb3 156 wait(0.1);
embeddedartists 2:2f4b7535ceb3 157
embeddedartists 2:2f4b7535ceb3 158 // Countdown
embeddedartists 2:2f4b7535ceb3 159 if (delays%10 == 0) {
embeddedartists 2:2f4b7535ceb3 160 printf("%ds\n", (80-delays)/10);
embeddedartists 2:2f4b7535ceb3 161 }
embeddedartists 2:2f4b7535ceb3 162 delays++;
embeddedartists 2:2f4b7535ceb3 163 }
embeddedartists 2:2f4b7535ceb3 164
embeddedartists 7:48375cb50f3a 165 int vh,vl,r,ty,att;
embeddedartists 7:48375cb50f3a 166 for (att = 1; att <= 5;att++) {
embeddedartists 7:48375cb50f3a 167 if (_touch.info(&vh,&vl,&r,&ty)) {
embeddedartists 7:48375cb50f3a 168 printf("Touch info: v%d.%d, %d-bit resolution, type 0x%x\n", vh, vl, r, ty);
embeddedartists 7:48375cb50f3a 169 break;
embeddedartists 7:48375cb50f3a 170 } else {
embeddedartists 7:48375cb50f3a 171 printf("Attempt %d to get touch controller info failed...\n", att);
embeddedartists 7:48375cb50f3a 172 wait(1);
embeddedartists 7:48375cb50f3a 173 }
embeddedartists 7:48375cb50f3a 174 }
embeddedartists 7:48375cb50f3a 175 if (att > 5) {
embeddedartists 7:48375cb50f3a 176 printf("Failed to read touch controller info even after %d attempts\n", att);
embeddedartists 2:2f4b7535ceb3 177 break;
embeddedartists 2:2f4b7535ceb3 178 }
embeddedartists 2:2f4b7535ceb3 179
embeddedartists 2:2f4b7535ceb3 180 printf("Calibrate display\n");
embeddedartists 2:2f4b7535ceb3 181 testPassed = calibrate_display();
embeddedartists 2:2f4b7535ceb3 182 } while(0);
embeddedartists 2:2f4b7535ceb3 183
embeddedartists 2:2f4b7535ceb3 184 _displayWorking = testPassed;
embeddedartists 2:2f4b7535ceb3 185 return testPassed;
embeddedartists 2:2f4b7535ceb3 186 }
embeddedartists 2:2f4b7535ceb3 187
embeddedartists 2:2f4b7535ceb3 188 void TestDisplay::drawBars() {
embeddedartists 2:2f4b7535ceb3 189 uint16_t* p = (uint16_t*)_framebuffer;
embeddedartists 2:2f4b7535ceb3 190 int third = _lcdCfg.width/3;
embeddedartists 2:2f4b7535ceb3 191 for (int y = 0; y < _lcdCfg.height; y++) {
embeddedartists 2:2f4b7535ceb3 192 int x;
embeddedartists 2:2f4b7535ceb3 193 for (x = 0; x < third; x++) {
embeddedartists 2:2f4b7535ceb3 194 *p = 0xf800;
embeddedartists 2:2f4b7535ceb3 195 p++;
embeddedartists 2:2f4b7535ceb3 196 }
embeddedartists 2:2f4b7535ceb3 197 for (; x < 2*third; x++) {
embeddedartists 2:2f4b7535ceb3 198 *p = 0x07e0;
embeddedartists 2:2f4b7535ceb3 199 p++;
embeddedartists 2:2f4b7535ceb3 200 }
embeddedartists 2:2f4b7535ceb3 201 for (; x < _lcdCfg.width; x++) {
embeddedartists 2:2f4b7535ceb3 202 *p = 0x001f;
embeddedartists 2:2f4b7535ceb3 203 p++;
embeddedartists 2:2f4b7535ceb3 204 }
embeddedartists 2:2f4b7535ceb3 205 }
embeddedartists 2:2f4b7535ceb3 206 }
embeddedartists 2:2f4b7535ceb3 207
embeddedartists 2:2f4b7535ceb3 208 void TestDisplay::calibrate_drawMarker(Graphics &g, uint16_t x, uint16_t y, bool erase) {
embeddedartists 2:2f4b7535ceb3 209 uint16_t color = (erase ? 0x0000 : 0xffff);
embeddedartists 2:2f4b7535ceb3 210 g.put_line(x-15, y, x+15, y, color);
embeddedartists 2:2f4b7535ceb3 211 g.put_line(x, y-15, x, y+15, color);
embeddedartists 2:2f4b7535ceb3 212 g.put_circle(x, y, color, 10, false);
embeddedartists 2:2f4b7535ceb3 213 }
embeddedartists 2:2f4b7535ceb3 214
embeddedartists 2:2f4b7535ceb3 215 bool TestDisplay::calibrate_display() {
embeddedartists 2:2f4b7535ceb3 216 bool morePoints = true;
embeddedartists 2:2f4b7535ceb3 217 uint16_t x, y;
embeddedartists 2:2f4b7535ceb3 218 int point = 0;
embeddedartists 2:2f4b7535ceb3 219 Graphics g((uint16_t*)_framebuffer, _lcdCfg.width, _lcdCfg.height);
embeddedartists 2:2f4b7535ceb3 220
embeddedartists 2:2f4b7535ceb3 221 do {
embeddedartists 2:2f4b7535ceb3 222 if (!_touch.init(_lcdCfg.width, _lcdCfg.height)) {
embeddedartists 2:2f4b7535ceb3 223 printf("Failed to initialize touch controller\n");
embeddedartists 2:2f4b7535ceb3 224 break;
embeddedartists 2:2f4b7535ceb3 225 }
embeddedartists 2:2f4b7535ceb3 226 if (!_touch.calibrateStart()) {
embeddedartists 2:2f4b7535ceb3 227 printf("Failed to start calibration\n");
embeddedartists 2:2f4b7535ceb3 228 break;
embeddedartists 2:2f4b7535ceb3 229 }
embeddedartists 2:2f4b7535ceb3 230 while (morePoints) {
embeddedartists 2:2f4b7535ceb3 231 if (point++ > 0) {
embeddedartists 2:2f4b7535ceb3 232 // erase old location
embeddedartists 2:2f4b7535ceb3 233 calibrate_drawMarker(g, x, y, true);
embeddedartists 2:2f4b7535ceb3 234 }
embeddedartists 2:2f4b7535ceb3 235 if (!_touch.getNextCalibratePoint(&x, &y)) {
embeddedartists 2:2f4b7535ceb3 236 printf("Failed to get calibration point\n");
embeddedartists 2:2f4b7535ceb3 237 break;
embeddedartists 2:2f4b7535ceb3 238 }
embeddedartists 2:2f4b7535ceb3 239 calibrate_drawMarker(g, x, y, false);
embeddedartists 2:2f4b7535ceb3 240 if (!_touch.waitForCalibratePoint(&morePoints, 0)) {
embeddedartists 2:2f4b7535ceb3 241 printf("Failed to get user click\n");
embeddedartists 2:2f4b7535ceb3 242 break;
embeddedartists 2:2f4b7535ceb3 243 }
embeddedartists 2:2f4b7535ceb3 244 }
embeddedartists 2:2f4b7535ceb3 245 if (morePoints) {
embeddedartists 2:2f4b7535ceb3 246 // aborted calibration due to error(s)
embeddedartists 2:2f4b7535ceb3 247 break;
embeddedartists 2:2f4b7535ceb3 248 }
embeddedartists 2:2f4b7535ceb3 249
embeddedartists 2:2f4b7535ceb3 250 // erase old location
embeddedartists 2:2f4b7535ceb3 251 calibrate_drawMarker(g, x, y, true);
embeddedartists 2:2f4b7535ceb3 252
embeddedartists 2:2f4b7535ceb3 253 // allow user to draw for 5 seconds
embeddedartists 2:2f4b7535ceb3 254 Timer t;
embeddedartists 2:2f4b7535ceb3 255 t.start();
embeddedartists 2:2f4b7535ceb3 256 TouchPanel::touchCoordinate_t tc;
embeddedartists 2:2f4b7535ceb3 257 while(t.read() < 6) {
embeddedartists 2:2f4b7535ceb3 258 if (_touch.read(tc)) {
embeddedartists 2:2f4b7535ceb3 259 //printf("TC: x,y,z = {%5d, %5d, %5d}\n", tc.x, tc.y, tc.z);
embeddedartists 2:2f4b7535ceb3 260 if (tc.z) {
embeddedartists 2:2f4b7535ceb3 261 g.put_dot(tc.x, tc.y, 0xffff);
embeddedartists 2:2f4b7535ceb3 262 }
embeddedartists 2:2f4b7535ceb3 263 }
embeddedartists 2:2f4b7535ceb3 264 }
embeddedartists 2:2f4b7535ceb3 265 } while(0);
embeddedartists 2:2f4b7535ceb3 266
embeddedartists 2:2f4b7535ceb3 267 return !morePoints;
embeddedartists 2:2f4b7535ceb3 268 }
embeddedartists 2:2f4b7535ceb3 269
embeddedartists 2:2f4b7535ceb3 270
embeddedartists 2:2f4b7535ceb3 271