Production Test Program (PTP) for the LPC4088 Experiment Base Board
Dependencies: EALib I2S LM75B SDFileSystem mbed
Diff: main.cpp
- Revision:
- 1:47680ec5d783
- Parent:
- 0:0d5190d379d3
- Child:
- 2:2f4b7535ceb3
--- a/main.cpp Mon Aug 25 13:15:27 2014 +0000 +++ b/main.cpp Wed Aug 27 14:24:59 2014 +0000 @@ -11,18 +11,72 @@ #include "TextLCD.h" #include "DmTftHX8353C.h" #include "BubbleDemo.h" +#include "AR1021I2C.h" +#include "Graphics.h" + +#include "LcdController.h" +#include "EaLcdBoardGPIO.h" +#include "sdram.h" /****************************************************************************** * Typedefs and defines *****************************************************************************/ +#define ACC_XMIN (1<<0) +#define ACC_XMAX (1<<1) +#define ACC_YMIN (1<<2) +#define ACC_YMAX (1<<3) +#define ACC_ZMIN (1<<4) +#define ACC_ZMAX (1<<5) + +#define ACC_MIN_LIMIT (-50) +#define ACC_MAX_LIMIT ( 50) + #define BUTTON_PRESSED 0 #define BUTTON_RELEASED 1 #define LED_ON 0 #define LED_OFF 1 -#define handleError(__a, __b) printf("Error: %s\n", (__b)); mbed_die() +#if 0 + // Enters eternal loop + #define handleError(__a, __b) do { \ + printf("Error " #__a ": %s\n", (__b)); \ + resetLEDs(); \ + ledRed = LED_ON; \ + ledGreen = LED_OFF; \ + ledBlue = LED_OFF; \ + mbed_die(); \ + } while(0) + + #define showTestResult() do {} while(0) // Never used in this setup +#else + bool allTestsPassed = true; + // Leaves error handling to the end of the program + #define handleError(__a, __b) do { \ + printf("Error " #__a ": %s\n", (__b)); \ + resetLEDs(); \ + *ledRed = LED_ON; \ + *ledGreen = LED_OFF; \ + *ledBlue = LED_OFF; \ + allTestsPassed = false; \ + return; \ + } while(0) + + #define showTestResult() do { \ + resetLEDs(); \ + *ledRed = LED_OFF; \ + *ledGreen = LED_OFF; \ + *ledBlue = LED_OFF; \ + if (allTestsPassed) { \ + printf("\n\nTest Result: PASSED\n\n"); \ + *ledGreen = LED_ON; \ + } else { \ + printf("\n\nTest Result: FAILED\n\n"); \ + *ledRed = LED_ON; \ + } \ + } while(0) +#endif #define waitForButtonClick() do {while(button.read() == BUTTON_RELEASED); while(button.read() == BUTTON_PRESSED);} while(false) @@ -30,25 +84,47 @@ * Local variables *****************************************************************************/ -//MCIFileSystem mcifs("mci");//, P4_16); -SDFileSystem spifs(p5, p6, p7, p8, "spi"); // mosi, miso, sclk, cs - DigitalOut myled(LED1); DigitalIn button(p23); SPI shiftreg(p5, p6, p7); // mosi, miso, sclk, DigitalOut shiftregCS(p30); -DigitalOut ledRed(p25); -DigitalOut ledGreen(p28); -DigitalOut ledBlue(p26); +DigitalOut* ledRed = NULL; +DigitalOut* ledGreen = NULL; +DigitalOut* ledBlue = NULL; /****************************************************************************** * Local functions *****************************************************************************/ +static void resetLEDs() +{ + // Some peripherals may interfer with the RGB LED and as a result it + // may be needed to reinitialize them so that PIN is again an GPIO. + if (ledRed != NULL) { + delete ledRed; + } + if (ledGreen != NULL) { + delete ledGreen; + } + if (ledBlue != NULL) { + delete ledBlue; + } + ledRed = new DigitalOut(p25); + ledGreen = new DigitalOut(p28); + ledBlue = new DigitalOut(p26); + + *ledRed = LED_OFF; + *ledGreen = LED_OFF; + *ledBlue = LED_OFF; +} + static void test_micro_sd_card_mci() { + // The LPC4088 Experiment Base Board does not have the CardDetect signal + // available so it must be set to NC here to work. + MCIFileSystem mcifs("mci", NC); FILE* fp = fopen("/mci/message.txt", "r"); if (fp != NULL) { char buf[20]; @@ -69,6 +145,7 @@ static void test_micro_sd_card_spi() { + SDFileSystem spifs(p5, p6, p7, p8, "spi"); // mosi, miso, sclk, cs FILE* fp = fopen("/spi/message.txt", "r"); if (fp != NULL) { char buf[20]; @@ -89,6 +166,52 @@ static void test_acc() { +#if 1 + MMA7455 sensor(P0_27, P0_28); + + //Try to initialize the accelerometer + if (!sensor.setMode(MMA7455::ModeMeasurement)) { + handleError(STATE_ERR_ACC, "Unable to set mode for MMA7455!\n"); + } + + if (!sensor.calibrate()) { + handleError(STATE_ERR_ACC, "Failed to calibrate MMA7455!\n"); + } + + int val[3] = { 0, 0, 0}; + int max[3] = {-1000,-1000,-1000}; + int min[3] = { 1000, 1000, 1000}; + int i; + Timer t; + t.start(); + while (t.read() < 5) { + if (!sensor.read(val[0], val[1], val[2])) { + handleError(STATE_ERR_ACC, "Failed to read accelerometer data!\n"); + } + printf("ACC: x,y,z = {%5d, %5d, %5d}\n", val[0], val[1], val[2]); + for (i = 0; i < 3; i++) { + if (val[i] < min[i]) { + min[i] = val[i]; + } + if (val[i] > max[i]) { + max[i] = val[i]; + } + } + for (i = 0; i < 3; i++) { + if ((max[i] - min[i]) < 2) { + break; + } + if (i == 2) { + printf("All three axis work\n"); + return; + } + } + wait(0.1); + } + printf("Not enough variation X {%d..%d}, Y {%d..%d}, Z {%d..%d}!\n", + min[0], max[0], min[1], max[1], min[2], max[2]); + handleError(STATE_ERR_ACC, "Accelerometer data invalid\n"); +#else MMA7455 sensor(P0_27, P0_28); //Try to initialize the accelerometer @@ -104,37 +227,73 @@ handleError(STATE_ERR_ACC, "Failed to calibrate MMA7455!\n"); } - printf("Printing values for the next 5 seconds...\n"); + printf("Now tilt the board in all directions (max 10 seconds)...\n"); int x=0, y=0, z=0; + uint8_t done = 0; + char msg[30] = {0}; Timer t; t.start(); - while (t.read() < 6) { + while ((t.read() < 10) && (done != 0x3f)) { if (!sensor.read(x, y, z)) { handleError(STATE_ERR_ACC, "Failed to read accelerometer data!\n"); } - printf("ACC: x,y,z = {%5d, %5d, %5d}\n", x, y, z); + printf("ACC: x,y,z = {%5d, %5d, %5d} %s\n", x, y, z, msg); + if ((x < ACC_MIN_LIMIT) && !(done & ACC_XMIN)) { + done |= ACC_XMIN; + printf("Tilted XMIN\n"); + } else if ((x > ACC_MAX_LIMIT) && !(done & ACC_XMAX)) { + done |= ACC_XMAX; + printf("Tilted XMAX\n"); + } + if ((y < ACC_MIN_LIMIT) && !(done & ACC_YMIN)) { + done |= ACC_YMIN; + printf("Tilted YMIN\n"); + } else if ((y > ACC_MAX_LIMIT) && !(done & ACC_YMAX)) { + done |= ACC_YMAX; + printf("Tilted XMAX\n"); + } + if ((z < ACC_MIN_LIMIT) && !(done & ACC_ZMIN)) { + done |= ACC_ZMIN; + printf("Tilted ZMIN\n"); + } else if ((z > ACC_MAX_LIMIT) && !(done & ACC_ZMAX)) { + done |= ACC_ZMAX; + printf("Tilted ZMAX\n"); + } + wait(0.1); } printf("Done with ACC tests!\n"); +#endif } static void test_lm75() { //Create an LM75B object at 0x92/0x93 (ADDRESS_1) LM75B sensor(P0_27, P0_28, LM75B::ADDRESS_1); - + + printf("Testing LM75 temperature sensor...\n"); + //Try to open the LM75B if (sensor.open()) { printf("LM75 Device detected!\n"); int i = 10; while (i--) { + float f = (float)sensor; //Print the current temperature - printf("Temp = %.3f\n", (float)sensor); + printf("Temp = %.3f\n", f); + if ((f >= 15) && (f <= 45)) { + printf("Temp in 15..45 range - test passed\n"); + break; + } + //Sleep for 0.5 seconds wait(0.5); } + if (i == 0) { + handleError(STATE_ERR_LM75, "LM75 No temp in range 15..45!\n"); + } } else { handleError(STATE_ERR_LM75, "LM75 Device not detected!\n"); } @@ -143,13 +302,27 @@ static void test_trimpot() { AnalogIn trimpot(p15); + bool min = false; + bool max = false; printf("Reading trimpot for 5 seconds...\n"); for (int i = 0; i < 50; i++) { - printf("Trimpot = %.3f\n", trimpot.read()); + float f = trimpot.read(); + printf("Trimpot = %.3f\n", f); + if (f < 0.01f) { + min = true; + } else if (f > 0.99f) { + max = true; + } + if (min && max) { + printf("Test passed\n"); + return; + } + wait(0.1); - } + } + handleError(STATE_ERR_TRIMPOT, "Trimpot does not reach limits (0.01 - 0.99)!\n"); } static void outputShiftReg(uint8_t val) @@ -217,47 +390,57 @@ } if (mask == 0x1F) { printf("All directions tested. Done!\n"); - break; + return; } wait(0.1); - } + if (i%10 == 0) { + printf("%ds\n", (100-i)/10); + } + } + handleError(STATE_ERR_JOYSTICK, "Failed to detect all joystick directions\n"); } static void test_rgb() { - printf("All off. Press button to continue\n"); - ledRed = LED_OFF; - ledGreen = LED_OFF; - ledBlue = LED_OFF; + printf("LED Tests: All off. Press button to continue\n"); + *ledRed = LED_OFF; + *ledGreen = LED_OFF; + *ledBlue = LED_OFF; waitForButtonClick(); - printf("RED on. Press button to continue\n"); - ledRed = LED_ON; - ledGreen = LED_OFF; - ledBlue = LED_OFF; + printf("LED Tests: RED on. Press button to continue\n"); + *ledRed = LED_ON; + *ledGreen = LED_OFF; + *ledBlue = LED_OFF; waitForButtonClick(); - printf("GREEN on. Press button to continue\n"); - ledRed = LED_OFF; - ledGreen = LED_ON; - ledBlue = LED_OFF; + printf("LED Tests: GREEN on. Press button to continue\n"); + *ledRed = LED_OFF; + *ledGreen = LED_ON; + *ledBlue = LED_OFF; waitForButtonClick(); - printf("BLUE on. Press button to continue\n"); - ledRed = LED_OFF; - ledGreen = LED_OFF; - ledBlue = LED_ON; + printf("LED Tests: BLUE on. Press button to continue\n"); + *ledRed = LED_OFF; + *ledGreen = LED_OFF; + *ledBlue = LED_ON; waitForButtonClick(); - printf("All on. Press button to continue\n"); - ledRed = LED_OFF; - ledGreen = LED_OFF; - ledBlue = LED_OFF; + printf("LED Tests: All on. Press button to continue\n"); + *ledRed = LED_ON; + *ledGreen = LED_ON; + *ledBlue = LED_ON; waitForButtonClick(); + + // Turn them off again + *ledRed = LED_OFF; + *ledGreen = LED_OFF; + *ledBlue = LED_OFF; } static void test_audio() { + printf("Testing audio...\n"); WM8731 audio(P0_27, P0_28); if (!audio.writeCmd(WM8731::REG_R15_RESET, 0x0000)) { handleError(STATE_ERR_AUDIO, "Failed to send command to audio codec\n"); @@ -301,45 +484,197 @@ bubbleDemo.run(750, 20); } +static void drawBars(int w, int h, uint32_t frameBuf) +{ + uint16_t* p = (uint16_t*)frameBuf; + int third = w/3; + for (int y = 0; y < h; y++) { + int x; + for (x = 0; x < third; x++) { + *p = 0xf800; + p++; + } + for (; x < 2*third; x++) { + *p = 0x07e0; + p++; + } + for (; x < w; x++) { + *p = 0x001f; + p++; + } + } +} + +static void 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); +} + +static void calibrate_display(TouchPanel* tp, uint32_t framebuffer, LcdController::Config &lcd) +{ + bool morePoints = true; + uint16_t x, y; + int point = 0; + Graphics g((uint16_t*)framebuffer, lcd.width, lcd.height); + if (!tp->init(lcd.width, lcd.height)) { + handleError(STATE_ERR_TOUCH, "Failed to initialize touch controller\n"); + } + if (!tp->calibrateStart()) { + handleError(STATE_ERR_TOUCH, "Failed to start calibration\n"); + } + while (morePoints) { + if (point++ > 0) { + // erase old location + calibrate_drawMarker(g, x, y, true); + } + if (!tp->getNextCalibratePoint(&x, &y)) { + handleError(STATE_ERR_TOUCH, "Failed to get calibration point\n"); + } + calibrate_drawMarker(g, x, y, false); + if (!tp->waitForCalibratePoint(&morePoints, 0)) { + handleError(STATE_ERR_TOUCH, "Failed to get user click\n"); + } + } + + // 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 (tp->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); + } + } + } +} + +static void test_Display() +{ + if (sdram_init() == 1) { + handleError(STATE_ERR_MEM, "Failed to initialize SDRAM\n"); + } + + // Test of display attached with FPC connector, 0.5mm pitch + EaLcdBoard::Result result; + LcdController::Config lcdCfg(40, 5, 2, 480, 8, 8, 2, 272, false, false, true, true, 1, LcdController::Bpp_16_565, 9000000, LcdController::Tft, false); + char* initStr = "v1,cd0,c50,cc0,c30,d100,c31,d100,cd1,d10,o,c51,cc100"; + EaLcdBoardGPIO lcdBoard(P0_27, P0_28); + int num = lcdCfg.width * lcdCfg.height * 2; + + uint32_t frameBuf = (uint32_t) malloc(num); + if (frameBuf == 0) { + handleError(STATE_ERR_MEM, "Failed to allocate memory for framebuffer\n"); + } + drawBars(lcdCfg.width, lcdCfg.height, frameBuf); + + result = lcdBoard.open(&lcdCfg, initStr); + if (result != EaLcdBoard::Ok) { + printf("Error Code: %d\n", result); + handleError(STATE_ERR_MEM, "Failed to open display\n"); + } + + result = lcdBoard.setFrameBuffer(frameBuf); + if (result != EaLcdBoard::Ok) { + printf("Error Code: %d\n", result); + handleError(STATE_ERR_MEM, "Failed to set framebuffer\n"); + } + + printf("Initialized. Control contrast with right trimpot (8 seconds)\n"); + AnalogIn trimpot(p15); + Timer t; + t.start(); + int delays = 0; + float last = -0.365; + while (t.read() < 8) { + float f = trimpot.read(); + if (f != last) { + last = f; + lcdBoard.setBC(100*f); + } + wait(0.1); + if (delays%10 == 0) { + printf("%ds\n", (80-delays)/10); + } + delays++; + } + + AR1021I2C touch(P0_27, P0_28, P2_25); + int vh,vl,r,ty; + if (touch.info(&vh,&vl,&r,&ty)) { + printf("Touch info: v%d.%d, %d-bit resolution, type 0x%x\n", vh, vl, r, ty); + } else { + printf("Failed to read touch information\n"); + } + + printf("Calibrate display\n"); + calibrate_display(&touch, frameBuf, lcdCfg); + if (allTestsPassed) { + memset((uint8_t*)frameBuf, 0x03, num); // GREEN + } else { + memset((uint8_t*)frameBuf, 0xe0, num); // RED + } +} + +static void setupSerial(int baudrate) +{ + // This works because both the default serial (used by printf) and the s instance + // (used by s.printf) would use the same underlying UART code so setting the baudrate + // in one affects the other. + Serial s(USBTX, USBRX); + s.baud(baudrate); +} + int main() { - printf("hello! " __DATE__ " at " __TIME__ "\n"); + setupSerial(115200); + printf("\n" + "---\n" + "Production Test Program: LPC4088 Experiment Base Board\n" + "Build Date: " __DATE__ " at " __TIME__ "\n" + "\n"); shiftregCS = 1; button.mode(PullUp); - ledRed = LED_OFF; - ledGreen = LED_OFF; - ledBlue = LED_OFF; + resetLEDs(); outputShiftReg(0x0); //startup flash behaviour for(int i=0; i<10; i++) { - ledRed = LED_ON; + *ledRed = LED_ON; wait(0.05); - ledRed = LED_OFF; + *ledRed = LED_OFF; wait(0.05); } wait(1.0); for(int i=0; i<10; i++) { - ledGreen = LED_ON; + *ledGreen = LED_ON; wait(0.05); - ledGreen = LED_OFF; + *ledGreen = LED_OFF; wait(0.05); } wait(1.0); for(int i=0; i<10; i++) { - ledBlue = LED_ON; + *ledBlue = LED_ON; wait(0.05); - ledBlue = LED_OFF; + *ledBlue = LED_OFF; wait(0.05); } wait(1.0); - //test_micro_sd_card_mci(); + test_micro_sd_card_mci(); + resetLEDs(); // MCI interface disables the RGB LED // test_micro_sd_card_spi(); test_acc(); test_lm75(); @@ -349,7 +684,12 @@ test_audio(); //test_TextLCD(); //test_DisplayModule(); - waitForButtonClick(); + + test_Display(); + + showTestResult(); + + //waitForButtonClick(); while(1) { test_shiftreg();