Production Test Program (PTP) for the LPC4088 Experiment Base Board
Dependencies: EALib I2S LM75B SDFileSystem mbed
Revision 0:0d5190d379d3, committed 2014-08-25
- Comitter:
- embeddedartists
- Date:
- Mon Aug 25 13:15:27 2014 +0000
- Child:
- 1:47680ec5d783
- Commit message:
- Baseline for PTP (production test program) for the LPC4088 QSB + Experiment Base Board.
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BubbleDemo.cpp Mon Aug 25 13:15:27 2014 +0000 @@ -0,0 +1,171 @@ +/****************************************************************************** + * Includes + *****************************************************************************/ + +#include "mbed.h" + +#include "BubbleDemo.h" +#include "DmTftBase.h" +#include "wchar.h" + +/****************************************************************************** + * Typedefs and defines + *****************************************************************************/ + +#define PI 3.1415926535897932384626433832795 + +/* Red color mask, 565 mode */ +#define REDMASK 0xF800 +/* Red shift value, 565 mode */ +#define REDSHIFT 11 +/* Green color mask, 565 mode */ +#define GREENMASK 0x07E0 +/* Green shift value, 565 mode */ +#define GREENSHIFT 5 +/* Blue color mask, 565 mode */ +#define BLUEMASK 0x001F +/* Blue shift value, 565 mode */ +#define BLUESHIFT 0 + +/* Number of colors in 565 mode */ +#define NUM_COLORS 65536 +/* Number of red colors in 565 mode */ +#define RED_COLORS 0x20 +/* Number of green colors in 565 mode */ +#define GREEN_COLORS 0x40 +/* Number of blue colors in 565 mode */ +#define BLUE_COLORS 0x20 + +/****************************************************************************** + * Local variables + *****************************************************************************/ + + +/****************************************************************************** + * External variables + *****************************************************************************/ + + +/****************************************************************************** + * Local functions + *****************************************************************************/ + + +void BubbleDemo::initialize() { + float radian; + const float phase1 = 2 * PI / 3; + const float phase2 = 4 * PI / 3; + + for(i = 0; i < NumBalls; i++) { + x[i] = this->windowX / 2; + y[i] = this->windowY / 2; + r[i] = i * 2 + 10; + + oldX[i] = x[i]; + oldY[i] = y[i]; + + velX[i] = 1; + velY[i] = 1; + + radian = i * 2 * PI / NumBalls; + red[i] = cos(radian) * RED_COLORS / 2 + (RED_COLORS / 2 - 1); + green[i] = cos(radian + phase2) * GREEN_COLORS / 2 + (GREEN_COLORS / 2 - 1); + blue[i] = cos(radian + phase1) * BLUE_COLORS / 2 + (BLUE_COLORS / 2 - 1); + } +} + +void BubbleDemo::collision() { + float disX = x[j] - x[i]; + float disY = y[j] - y[i]; + float d2 = disX * disX + disY * disY; + + if(d2 != 0) { + float rij = r[i] + r[j]; + float rij2 = rij * rij; + + if(d2 < rij2) { + float ii = (disX * velX[i] + disY * velY[i]) / d2; + float ji = (disX * velY[i] - disY * velX[i]) / d2; + float ij = (disX * velX[j] + disY * velY[j]) / d2; + float jj = (disX * velY[j] - disY * velX[j]) / d2; + float ratio = rij / sqrt(d2); + + velX[i] = ij * disX - ii * disY; + velY[i] = ij * disY + ii * disX; + velX[j] = ji * disX - jj * disY; + velY[j] = ji * disY + jj * disX; + + disX *= (ratio - 1) / 2; + disY *= (ratio - 1) / 2; + + x[j] += disX; + y[j] += disY; + x[i] -= disX; + y[i] -= disY; + } + } +} + +void BubbleDemo::borders() { + if(x[i] >= this->windowX - r[i] - 1) { + x[i] = this->windowX - r[i] - 1; + velX[i] = -velX[i]; + } else if(x[i] <= r[i]) { + x[i] = r[i]; + velX[i] = -velX[i]; + } + + if(y[i] >= this->windowY - r[i] - 1) { + y[i] = this->windowY - r[i] - 1; + velY[i] = -velY[i]; + } else if(y[i] <= r[i]) { + y[i] = r[i]; + velY[i] = -velY[i]; + } +} + +void BubbleDemo::draw() { + tft->drawCircle(oldX[i], oldY[i], r[i], BLACK); + tft->drawCircle(x[i], y[i], r[i], (red[i] << REDSHIFT) + (green[i] << GREENSHIFT) + (blue[i] << BLUESHIFT)); + + oldX[i] = x[i]; + oldY[i] = y[i]; +} + + +/****************************************************************************** + * Public functions + *****************************************************************************/ + +BubbleDemo::BubbleDemo(DmTftBase* display, uint16_t dispWidth, uint16_t dispHeight) { + + this->windowX = dispWidth; + this->windowY = dispHeight; + tft = display; + + initialize(); +} + +void BubbleDemo::run(uint32_t loops, uint32_t delayMs) { + + tft->clearScreen(); + + for(int32_t n=0;n<loops;n++) { + + for(i = 0; i < NumBalls; i++) { + x[i] += velX[i]; + y[i] += velY[i]; + + for(j = i + 1; j < NumBalls; j++) + collision(); + + borders(); + + if((int)x[i] != (int)oldX[i] || (int)y[i] != (int)oldY[i]) + draw(); + } + + wait_ms(delayMs); + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BubbleDemo.h Mon Aug 25 13:15:27 2014 +0000 @@ -0,0 +1,68 @@ + +#ifndef BUBBLEDEMO_H +#define BUBBLEDEMO_H + +#include "DmTftBase.h" + +class BubbleDemo { +public: + + enum Constants { + NumBalls = 4 // 17 + }; + + /** Set the address of the frame buffer to use. + * + * It is the content of the frame buffer that is shown on the + * display. All the drawing on the frame buffer can be done + * 'offline' and whenever it should be shown this function + * can be called with the address of the offline frame buffer. + * + * @param pFrameBuf Pointer to the frame buffer, which must be + * 3 times as big as the frame size (for tripple + * buffering). + * dispWidth The width of the display (in pixels). + * dispHeight The height of the display (in pixels). + * loops Number of loops in the demo code. + * delayMs Delay in milliseconds between schreen updates. + * + * @returns + * none + */ + BubbleDemo(DmTftBase* display, uint16_t dispWidth, uint16_t dispHeight); + + void run(uint32_t loops, uint32_t delayMs); + +private: + int32_t windowX; + int32_t windowY; + + DmTftBase* tft; + + uint8_t i; + uint8_t j; + + float x[NumBalls]; + float y[NumBalls]; + uint8_t r[NumBalls]; + + float oldX[NumBalls]; + float oldY[NumBalls]; + + float velX[NumBalls]; + float velY[NumBalls]; + + uint8_t red[NumBalls]; + uint8_t green[NumBalls]; + uint8_t blue[NumBalls]; + + + void initialize(); + void collision(); + void borders(); + void draw(); +}; + +#endif /* BUBBLEDEMO_H */ + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DmTftLibrary.lib Mon Aug 25 13:15:27 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/displaymodule/code/DmTftLibrary/#d263094e666d
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/EALib.lib Mon Aug 25 13:15:27 2014 +0000 @@ -0,0 +1,1 @@ +https://mbed.org/users/embeddedartists/code/EALib/#529fb3f8f88b
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/LM75B.lib Mon Aug 25 13:15:27 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/neilt6/code/LM75B/#7ac462ba84ac
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SDFileSystem.lib Mon Aug 25 13:15:27 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/teams/mbed/code/SDFileSystem/#99e5b2187636
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TextLCD.lib Mon Aug 25 13:15:27 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/wim/code/TextLCD/#59c4b8f648d4
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/WM8731.cpp Mon Aug 25 13:15:27 2014 +0000 @@ -0,0 +1,61 @@ +/* + * 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 "mbed_debug.h" + +#include "WM8731.h" + +/****************************************************************************** + * Defines and typedefs + *****************************************************************************/ + +#define WM8731_I2C_ADDR (0x1A << 1) + +#define WM8731_REG_R0_LEFT_LINE_IN 0x00 +#define WM8731_REG_R1_RIGHT_LINE_IN 0x01 +#define WM8731_REG_R2_LEFT_HP_OUT 0x02 +#define WM8731_REG_R3_RIGHT_HP_OUT 0x03 +#define WM8731_REG_R4_ANALOGUE_AUDIO_PATH_CONTROL 0x04 +#define WM8731_REG_R5_DIGITAL_AUDIO_PATH_CONTROL 0x05 +#define WM8731_REG_R6_POWER_DOWN_CONTROL 0x06 +#define WM8731_REG_R7_DIGITAL_AUDIO_INTERFACE_FORMAT 0x07 +#define WM8731_REG_R8_SAMPLING_CONTROL 0x08 +#define WM8731_REG_R9_ACTIVE_CONTROL 0x09 +#define WM8731_REG_R15_RESET 0x0f + + +WM8731::WM8731(PinName sda, PinName scl) : _i2c(sda, scl) { +} + +bool WM8731::writeCmd(Register reg, uint16_t data) { + char dataToTransfer[2]; + + dataToTransfer[0] = (reg << 1) | ((data & 0x100) >> 8); + dataToTransfer[1] = data & 0xff; + + if (_i2c.write(WM8731_I2C_ADDR, dataToTransfer, 2) == 0) { + wait_us(40); + return true; + } + return false; +} + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/WM8731.h Mon Aug 25 13:15:27 2014 +0000 @@ -0,0 +1,67 @@ +/* + * 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. + */ + +#ifndef WM8731_H +#define WM8731_H + + +/** + * Wolfson Mgiroelectronics Audio Codec WM8731. + */ +class WM8731 { +public: + + /** Registers */ + enum Register { + REG_R0_LEFT_LINE_IN = 0x00, + REG_R1_RIGHT_LINE_IN = 0x01, + REG_R2_LEFT_HP_OUT = 0x02, + REG_R3_RIGHT_HP_OUT = 0x03, + REG_R4_ANALOGUE_AUDIO_PATH_CONTROL = 0x04, + REG_R5_DIGITAL_AUDIO_PATH_CONTROL = 0x05, + REG_R6_POWER_DOWN_CONTROL = 0x06, + REG_R7_DIGITAL_AUDIO_INTERFACE_FORMAT = 0x07, + REG_R8_SAMPLING_CONTROL = 0x08, + REG_R9_ACTIVE_CONTROL = 0x09, + REG_R15_RESET = 0x0f + }; + + /** + * Create an interface to the WM8731 accelerometer + * + * @param sda I2C data line pin + * @param scl I2C clock line pin + */ + WM8731(PinName sda, PinName scl); + + /** + * Write data to the specified address. + * + * @param reg register to write to + * @param data data to write + * + * @return true if command was successful; otherwise false + */ + bool writeCmd(Register reg, uint16_t data); + +private: + + I2C _i2c; +}; + +#endif + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Mon Aug 25 13:15:27 2014 +0000 @@ -0,0 +1,361 @@ +/****************************************************************************** + * 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" + +/****************************************************************************** + * Typedefs and defines + *****************************************************************************/ + +#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() + +#define waitForButtonClick() do {while(button.read() == BUTTON_RELEASED); while(button.read() == BUTTON_PRESSED);} while(false) + +/****************************************************************************** + * 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); + +/****************************************************************************** + * Local functions + *****************************************************************************/ + +static void test_micro_sd_card_mci() +{ + 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() +{ + 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() +{ + 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("Printing values for the next 5 seconds...\n"); + int x=0, y=0, z=0; + + Timer t; + t.start(); + while (t.read() < 6) { + 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("Done with ACC tests!\n"); +} + +static void test_lm75() +{ + //Create an LM75B object at 0x92/0x93 (ADDRESS_1) + LM75B sensor(P0_27, P0_28, LM75B::ADDRESS_1); + + //Try to open the LM75B + if (sensor.open()) { + printf("LM75 Device detected!\n"); + + int i = 10; + while (i--) { + //Print the current temperature + printf("Temp = %.3f\n", (float)sensor); + + //Sleep for 0.5 seconds + wait(0.5); + } + } else { + handleError(STATE_ERR_LM75, "LM75 Device not detected!\n"); + } +} + +static void test_trimpot() +{ + AnalogIn trimpot(p15); + + printf("Reading trimpot for 5 seconds...\n"); + + for (int i = 0; i < 50; i++) { + printf("Trimpot = %.3f\n", trimpot.read()); + wait(0.1); + } +} + +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"); + break; + } + wait(0.1); + } +} + +static void test_rgb() +{ + printf("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; + waitForButtonClick(); + + printf("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; + waitForButtonClick(); + + printf("All on. Press button to continue\n"); + ledRed = LED_OFF; + ledGreen = LED_OFF; + ledBlue = LED_OFF; + waitForButtonClick(); +} + +static void test_audio() +{ + 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); +} + +int main() { + printf("hello! " __DATE__ " at " __TIME__ "\n"); + + shiftregCS = 1; + button.mode(PullUp); + + ledRed = LED_OFF; + ledGreen = LED_OFF; + ledBlue = LED_OFF; + + 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(); +// test_micro_sd_card_spi(); + test_acc(); + test_lm75(); + test_trimpot(); + test_joystick(); + test_rgb(); + test_audio(); + //test_TextLCD(); + //test_DisplayModule(); + waitForButtonClick(); + + while(1) { + test_shiftreg(); + myled = 1; + wait(0.2); + myled = 0; + wait(0.2); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Mon Aug 25 13:15:27 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/9327015d4013 \ No newline at end of file