Production Test Program (PTP) for the LPC4088 Experiment Base Board
Dependencies: EALib I2S LM75B SDFileSystem mbed
TestDisplay.cpp
- Committer:
- embeddedartists
- Date:
- 2014-10-01
- Revision:
- 9:eb6086159020
- Parent:
- 7:48375cb50f3a
File content as of revision 9:eb6086159020:
/* * 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 "TestDisplay.h" #include "sdram.h" /****************************************************************************** * Defines and typedefs *****************************************************************************/ #define LCD_CONFIGURATION \ 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 (char*)"v1,cd0,c50,cc0,c30,d100,c31,d100,cd1,d10,o,c51,cc100" /****************************************************************************** * Public Functions *****************************************************************************/ /* Prerequisites: - A display must be connected to the LPC4088 Experiment Base Board with the FPC connector - The touch controller uses the I2C bus so for this test to work jumpers JP8 and JP9 on the LPC4088 Experiment Base Board must both be in positions 1-2 */ /* Test Description: - The SDRAM is initialized and a framebuffer is allocated - Display is initialized and a color bar (red-green-blue) is shown - The user have 10 seconds to test display contrast by turning the right trimpot on the board - The touch calibration is started and the user must press each of the four crosshairs that appear. - After calibration the display can be drawn upon for 5 seconds. Any failed part test will abort the sequence */ TestDisplay::TestDisplay() : _lcdCfg(LCD_CONFIGURATION), _lcdBoard(P0_27, P0_28), _touch(P0_27, P0_28, P2_25) { if (sdram_init() == 1) { printf("Failed to initialize SDRAM\n"); _framebuffer = 0; } else { _framebuffer = (uint32_t) malloc(_lcdCfg.width * _lcdCfg.height * 2); } _displayWorking = false; } TestDisplay::~TestDisplay() { if (_framebuffer != 0) { free((void*)_framebuffer); _framebuffer = 0; } } void TestDisplay::showStatus(bool success) { if (_displayWorking) { if (success) { // Green cannot be memsetted so it will have to be the // more manual way uint16_t* p = (uint16_t*)_framebuffer; for (int x = _lcdCfg.width; x > 0; x--) { for (int y = _lcdCfg.height; y > 0; y--) { *p++ = 0x07e0; } } } else { // Red is possible to set directly as 0xe0e0 in RGB565 have // only significant RED bits set. memset((uint8_t*)_framebuffer, 0xe0, _lcdCfg.width * _lcdCfg.height * 2); // RED } } } bool TestDisplay::runTest() { bool testPassed = false; do { if (_framebuffer == 0) { printf("Failed to allocate memory for framebuffer\n"); break; } // Prepare framebuffer drawBars(); EaLcdBoard::Result result = _lcdBoard.open(&_lcdCfg, LCD_INIT_STRING); if (result != EaLcdBoard::Ok) { printf("Failed to open display, error %d\n", result); break; } result = _lcdBoard.setFrameBuffer(_framebuffer); if (result != EaLcdBoard::Ok) { printf("Failed to set framebuffer, error %d\n", result); break; } printf("Initialized. Control contrast with right trimpot (8 seconds)\n"); AnalogIn trimpot(p15); Timer t; t.start(); int delays = 0; float last = -0.999; while (t.read() < 8) { float f = trimpot.read(); if (f != last) { last = f; _lcdBoard.setBC(100*f); // contrast is in 0..100 and analog value is 0.000..1.000 } wait(0.1); // Countdown if (delays%10 == 0) { printf("%ds\n", (80-delays)/10); } delays++; } int vh,vl,r,ty,att; for (att = 1; att <= 5;att++) { if (_touch.info(&vh,&vl,&r,&ty)) { printf("Touch info: v%d.%d, %d-bit resolution, type 0x%x\n", vh, vl, r, ty); break; } else { printf("Attempt %d to get touch controller info failed...\n", att); wait(1); } } if (att > 5) { printf("Failed to read touch controller info even after %d attempts\n", att); break; } printf("Calibrate display\n"); testPassed = calibrate_display(); } while(0); _displayWorking = testPassed; return testPassed; } void TestDisplay::drawBars() { uint16_t* p = (uint16_t*)_framebuffer; int third = _lcdCfg.width/3; for (int y = 0; y < _lcdCfg.height; y++) { int x; for (x = 0; x < third; x++) { *p = 0xf800; p++; } for (; x < 2*third; x++) { *p = 0x07e0; p++; } for (; x < _lcdCfg.width; x++) { *p = 0x001f; p++; } } } void TestDisplay::calibrate_drawMarker(Graphics &g, uint16_t x, uint16_t y, bool erase) { uint16_t color = (erase ? 0x0000 : 0xffff); g.put_line(x-15, y, x+15, y, color); g.put_line(x, y-15, x, y+15, color); g.put_circle(x, y, color, 10, false); } bool TestDisplay::calibrate_display() { bool morePoints = true; uint16_t x, y; int point = 0; Graphics g((uint16_t*)_framebuffer, _lcdCfg.width, _lcdCfg.height); do { if (!_touch.init(_lcdCfg.width, _lcdCfg.height)) { printf("Failed to initialize touch controller\n"); break; } if (!_touch.calibrateStart()) { printf("Failed to start calibration\n"); break; } while (morePoints) { if (point++ > 0) { // erase old location calibrate_drawMarker(g, x, y, true); } if (!_touch.getNextCalibratePoint(&x, &y)) { printf("Failed to get calibration point\n"); break; } calibrate_drawMarker(g, x, y, false); if (!_touch.waitForCalibratePoint(&morePoints, 0)) { printf("Failed to get user click\n"); break; } } if (morePoints) { // aborted calibration due to error(s) break; } // erase old location calibrate_drawMarker(g, x, y, true); // allow user to draw for 5 seconds Timer t; t.start(); TouchPanel::touchCoordinate_t tc; while(t.read() < 6) { if (_touch.read(tc)) { //printf("TC: x,y,z = {%5d, %5d, %5d}\n", tc.x, tc.y, tc.z); if (tc.z) { g.put_dot(tc.x, tc.y, 0xffff); } } } } while(0); return !morePoints; }