![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
Production Test Program (PTP) for the LPC4088 Experiment Base Board
Dependencies: EALib I2S LM75B SDFileSystem mbed
main.cpp
- Committer:
- embeddedartists
- Date:
- 2014-08-27
- Revision:
- 1:47680ec5d783
- Parent:
- 0:0d5190d379d3
- Child:
- 2:2f4b7535ceb3
File content as of revision 1:47680ec5d783:
/****************************************************************************** * Includes *****************************************************************************/ #include "mbed.h" #include "MCIFileSystem.h" #include "SDFileSystem.h" #include "LM75B.h" #include "MMA7455.h" #include "WM8731.h" #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 #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) /****************************************************************************** * Local variables *****************************************************************************/ DigitalOut myled(LED1); DigitalIn button(p23); SPI shiftreg(p5, p6, p7); // mosi, miso, sclk, DigitalOut shiftregCS(p30); 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]; int num = fread(buf, 1, sizeof(buf), fp); if (num >= 10) { buf[10] = '\0'; if (strcmp(buf, "eatest2014") == 0) { printf("MCI SD Card works!\n"); fclose(fp); return; } handleError(STATE_ERR_MCIFS, "Invalid data read from /mci/message.txt\n"); } handleError(STATE_ERR_MCIFS, "Failed to read >= 10 bytes from /mci/message.txt\n"); } handleError(STATE_ERR_MCIFS, "Failed to open /mci/message.txt\n"); } 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]; int num = fread(buf, 1, sizeof(buf), fp); if (num >= 10) { buf[10] = '\0'; if (strcmp(buf, "eatest2014") == 0) { printf("SPI SD Card works!\n"); fclose(fp); return; } handleError(STATE_ERR_SPIFS, "Invalid data read from /spi/message.txt\n"); } handleError(STATE_ERR_SPIFS, "Failed to read >= 10 bytes from /spi/message.txt\n"); } handleError(STATE_ERR_SPIFS, "Failed to open /spi/message.txt\n"); } 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 if (!sensor.setMode(MMA7455::ModeMeasurement)) { handleError(STATE_ERR_ACC, "Unable to set mode for MMA7455!\n"); } printf("Put on flat surface and press button to calibrate!\n"); while (button.read() != BUTTON_PRESSED) {} while (button.read() == BUTTON_PRESSED) {} if (!sensor.calibrate()) { handleError(STATE_ERR_ACC, "Failed to calibrate MMA7455!\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() < 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} %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", 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"); } } 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++) { 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) { shiftregCS = 0; shiftreg.write(val); shiftregCS = 1; } static void test_shiftreg() { outputShiftReg(0x1); wait(0.1); outputShiftReg(0x2); wait(0.1); outputShiftReg(0x4); wait(0.1); outputShiftReg(0x8); wait(0.1); outputShiftReg(0x10); wait(0.1); outputShiftReg(0x20); wait(0.1); outputShiftReg(0x40); wait(0.1); outputShiftReg(0x80); wait(0.1); outputShiftReg(0x40); wait(0.1); outputShiftReg(0x20); wait(0.1); outputShiftReg(0x10); wait(0.1); outputShiftReg(0x8); wait(0.1); outputShiftReg(0x4); wait(0.1); outputShiftReg(0x2); wait(0.1); outputShiftReg(0x1); wait(0.1); outputShiftReg(0x0); } static void test_joystick() { DigitalIn up(p32);//p39); DigitalIn down(p38);//p32); DigitalIn left(p39);//p38); DigitalIn right(p37); DigitalIn center(p31); printf("Reading joystick for 10 seconds or all directions...\n"); uint16_t mask = 0; for (int i = 0; i < 100; i++) { bool line = false; if (up.read() == 0) { printf("UP "); line = true; mask |= 0x01; } if (down.read() == 0) { printf("DOWN "); line = true; mask |= 0x02; } if (left.read() == 0) { printf("LEFT "); line = true; mask |= 0x04; } if (right.read() == 0) { printf("RIGHT "); line = true; mask |= 0x08; } if (center.read() == 0) { printf("CENTER ");line = true; mask |= 0x10; } if (line) { printf("\n"); } if (mask == 0x1F) { printf("All directions tested. Done!\n"); 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("LED Tests: All off. Press button to continue\n"); *ledRed = LED_OFF; *ledGreen = LED_OFF; *ledBlue = LED_OFF; waitForButtonClick(); printf("LED Tests: RED on. Press button to continue\n"); *ledRed = LED_ON; *ledGreen = LED_OFF; *ledBlue = LED_OFF; waitForButtonClick(); printf("LED Tests: GREEN on. Press button to continue\n"); *ledRed = LED_OFF; *ledGreen = LED_ON; *ledBlue = LED_OFF; waitForButtonClick(); printf("LED Tests: BLUE on. Press button to continue\n"); *ledRed = LED_OFF; *ledGreen = LED_OFF; *ledBlue = LED_ON; waitForButtonClick(); 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"); } } static void test_TextLCD() { SPI spi_lcd(p5, p6, p7); // MOSI, MISO, SCLK TextLCD_SPI lcd(&spi_lcd, p30, TextLCD::LCD16x2); // SPI bus, CS pin, LCD Type ok lcd.cls(); lcd.locate(0, 0); lcd.putc('E'); lcd.putc('m'); lcd.putc('b'); lcd.putc('e'); lcd.putc('d'); lcd.putc('d'); lcd.putc('e'); lcd.putc('d'); lcd.putc(' '); lcd.putc('A'); lcd.putc('r'); lcd.putc('t'); lcd.putc('i'); lcd.putc('s'); lcd.putc('t'); lcd.putc('s'); lcd.putc('!'); lcd.setCursor(TextLCD::CurOff_BlkOn); } static void test_DisplayModule() { // Test of DM-TFT18-101 display (http://www.displaymodule.com/collections/featured-modules/products/dm-tft18-101) DmTftHX8353C tft(p5, p7, p30, p17, p16); // mosi, clk, cs, dc, rst tft.init(); BubbleDemo bubbleDemo(&tft, tft.width(), tft.height()); 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() { 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); resetLEDs(); outputShiftReg(0x0); //startup flash behaviour for(int i=0; i<10; i++) { *ledRed = LED_ON; wait(0.05); *ledRed = LED_OFF; wait(0.05); } wait(1.0); for(int i=0; i<10; i++) { *ledGreen = LED_ON; wait(0.05); *ledGreen = LED_OFF; wait(0.05); } wait(1.0); for(int i=0; i<10; i++) { *ledBlue = LED_ON; wait(0.05); *ledBlue = LED_OFF; wait(0.05); } wait(1.0); test_micro_sd_card_mci(); resetLEDs(); // MCI interface disables the RGB LED // test_micro_sd_card_spi(); test_acc(); test_lm75(); test_trimpot(); test_joystick(); test_rgb(); test_audio(); //test_TextLCD(); //test_DisplayModule(); test_Display(); showTestResult(); //waitForButtonClick(); while(1) { test_shiftreg(); myled = 1; wait(0.2); myled = 0; wait(0.2); } }