Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Revision 0:d1e4929f6956, committed 2014-10-03
- Comitter:
- embeddedartists
- Date:
- Fri Oct 03 13:37:30 2014 +0000
- Commit message:
- First version
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/AR1021I2C.cpp Fri Oct 03 13:37:30 2014 +0000
@@ -0,0 +1,560 @@
+/*
+ * 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 "AR1021I2C.h"
+
+/******************************************************************************
+ * Defines and typedefs
+ *****************************************************************************/
+
+#define AR1021_REG_TOUCH_THRESHOLD (0x02)
+#define AR1021_REG_SENS_FILTER (0x03)
+#define AR1021_REG_SAMPLING_FAST (0x04)
+#define AR1021_REG_SAMPLING_SLOW (0x05)
+#define AR1021_REG_ACC_FILTER_FAST (0x06)
+#define AR1021_REG_ACC_FILTER_SLOW (0x07)
+#define AR1021_REG_SPEED_THRESHOLD (0x08)
+#define AR1021_REG_SLEEP_DELAY (0x0A)
+#define AR1021_REG_PEN_UP_DELAY (0x0B)
+#define AR1021_REG_TOUCH_MODE (0x0C)
+#define AR1021_REG_TOUCH_OPTIONS (0x0D)
+#define AR1021_REG_CALIB_INSETS (0x0E)
+#define AR1021_REG_PEN_STATE_REPORT_DELAY (0x0F)
+#define AR1021_REG_TOUCH_REPORT_DELAY (0x11)
+
+
+#define AR1021_CMD_GET_VERSION (0x10)
+#define AR1021_CMD_ENABLE_TOUCH (0x12)
+#define AR1021_CMD_DISABLE_TOUCH (0x13)
+#define AR1021_CMD_CALIBRATE_MODE (0x14)
+#define AR1021_CMD_REGISTER_READ (0x20)
+#define AR1021_CMD_REGISTER_WRITE (0x21)
+#define AR1021_CMD_REGISTER_START_ADDR_REQUEST (0x22)
+#define AR1021_CMD_REGISTER_WRITE_TO_EEPROM (0x23)
+#define AR1021_CMD_EEPROM_READ (0x28)
+#define AR1021_CMD_EEPROM_WRITE (0x29)
+#define AR1021_CMD_EEPROM_WRITE_TO_REGISTERS (0x2B)
+
+#define AR1021_RESP_STAT_OK (0x00)
+#define AR1021_RESP_STAT_CMD_UNREC (0x01)
+#define AR1021_RESP_STAT_HDR_UNREC (0x03)
+#define AR1021_RESP_STAT_TIMEOUT (0x04)
+#define AR1021_RESP_STAT_CANCEL_CALIB (0xFC)
+
+
+#define AR1021_ERR_NO_HDR (-1000)
+#define AR1021_ERR_INV_LEN (-1001)
+#define AR1021_ERR_INV_RESP (-1002)
+#define AR1021_ERR_INV_RESPLEN (-1003)
+#define AR1021_ERR_TIMEOUT (-1004)
+
+// bit 7 is always 1 and bit 0 defines pen up or down
+#define AR1021_PEN_MASK (0x81)
+
+#define AR1021_NUM_CALIB_POINTS (4)
+
+#define AR1021_ADDR (0x4D << 1)
+
+#define AR1021_TIMEOUT 1000 //how many ms to wait for responce
+#define AR1021_RETRY 5 //how many times to retry sending command
+
+#define AR1021_MIN(__a, __b) (((__a)<(__b))?(__a):(__b))
+
+
+AR1021I2C::AR1021I2C(PinName sda, PinName scl, PinName siq) :
+_i2c(sda, scl), _siq(siq), _siqIrq(siq)
+{
+ _i2c.frequency(200000);
+
+ // default calibration inset is 25 -> (25/2 = 12.5%)
+ _inset = 25;
+
+ // make sure _calibPoint has an invalid value to begin with
+ // correct value is set in calibrateStart()
+ _calibPoint = AR1021_NUM_CALIB_POINTS+1;
+
+ _x = 0;
+ _y = 0;
+ _pen = 0;
+
+ _initialized = false;
+}
+
+
+bool AR1021I2C::read(touchCoordinate_t &coord) {
+
+ if (!_initialized) return false;
+
+ coord.x = _x * _width/4095;
+ coord.y = _y * _height/4095;
+ coord.z = _pen;
+
+ return true;
+}
+
+
+bool AR1021I2C::init(uint16_t width, uint16_t height) {
+ int result = 0;
+ bool ok = false;
+ int attempts = 0;
+
+ _width = width;
+ _height = height;
+
+ while (1) {
+
+ do {
+ // disable touch
+ result = cmd(AR1021_CMD_DISABLE_TOUCH, NULL, 0, NULL, 0);
+ if (result != 0) {
+ debug("disable touch failed (%d)\n", result);
+ break;
+ }
+
+ char regOffset = 0;
+ int regOffLen = 1;
+ result = cmd(AR1021_CMD_REGISTER_START_ADDR_REQUEST, NULL, 0,
+ ®Offset, ®OffLen);
+ if (result != 0) {
+ debug("register offset request failed (%d)\n", result);
+ break;
+ }
+
+ // enable calibrated coordinates
+ // high, low address, len, value
+ char toptions[4] = {0x00, AR1021_REG_TOUCH_OPTIONS+regOffset, 0x01, 0x01};
+ result = cmd(AR1021_CMD_REGISTER_WRITE, toptions, 4, NULL, 0);
+ if (result != 0) {
+ debug("register write request failed (%d)\n", result);
+ break;
+ }
+
+ // save registers to eeprom
+ result = cmd(AR1021_CMD_REGISTER_WRITE_TO_EEPROM, NULL, 0, NULL, 0);
+ if (result != 0) {
+ debug("register write to eeprom failed (%d)\n", result);
+ break;
+ }
+
+ // enable touch
+ result = cmd(AR1021_CMD_ENABLE_TOUCH, NULL, 0, NULL, 0);
+ if (result != 0) {
+ debug("enable touch failed (%d)\n", result);
+ break;
+ }
+
+ _siqIrq.rise(this, &AR1021I2C::readTouchIrq);
+
+ _initialized = true;
+ ok = true;
+
+ } while(0);
+
+ if (ok) break;
+
+ // try to run the initialize sequence at most 2 times
+ if(++attempts >= 2) break;
+ }
+
+
+ return ok;
+}
+
+bool AR1021I2C::calibrateStart() {
+ bool ok = false;
+ int result = 0;
+ int attempts = 0;
+
+ if (!_initialized) return false;
+
+ _siqIrq.rise(NULL);
+
+ while(1) {
+
+ do {
+ // disable touch
+ result = cmd(AR1021_CMD_DISABLE_TOUCH, NULL, 0, NULL, 0);
+ if (result != 0) {
+ debug("disable touch failed (%d)\n", result);
+ break;
+ }
+
+ char regOffset = 0;
+ int regOffLen = 1;
+ result = cmd(AR1021_CMD_REGISTER_START_ADDR_REQUEST, NULL, 0,
+ ®Offset, ®OffLen);
+ if (result != 0) {
+ debug("register offset request failed (%d)\n", result);
+ break;
+ }
+
+ // set insets
+ // enable calibrated coordinates
+ // high, low address, len, value
+ char insets[4] = {0x00, AR1021_REG_CALIB_INSETS+regOffset, 0x01, _inset};
+ result = cmd(AR1021_CMD_REGISTER_WRITE, insets, 4, NULL, 0);
+ if (result != 0) {
+ debug("register write request failed (%d)\n", result);
+ break;
+ }
+
+ // calibration mode
+ char calibType = 4;
+ result = cmd(AR1021_CMD_CALIBRATE_MODE, &calibType, 1, NULL, 0, false);
+ if (result != 0) {
+ debug("calibration mode failed (%d)\n", result);
+ break;
+ }
+
+ _calibPoint = 0;
+ ok = true;
+
+ } while(0);
+
+ if (ok) break;
+
+ // try to run the calibrate mode sequence at most 2 times
+ if (++attempts >= 2) break;
+ }
+
+ return ok;
+}
+
+bool AR1021I2C::getNextCalibratePoint(uint16_t* x, uint16_t* y) {
+
+ if (!_initialized) return false;
+ if (x == NULL || y == NULL) return false;
+
+ int xInset = (_width * _inset / 100) / 2;
+ int yInset = (_height * _inset / 100) / 2;
+
+ switch(_calibPoint) {
+ case 0:
+ *x = xInset;
+ *y = yInset;
+ break;
+ case 1:
+ *x = _width - xInset;
+ *y = yInset;
+ break;
+ case 2:
+ *x = _width - xInset;
+ *y = _height - yInset;
+ break;
+ case 3:
+ *x = xInset;
+ *y = _height - yInset;
+ break;
+ default:
+ return false;
+ }
+
+ return true;
+}
+
+bool AR1021I2C::waitForCalibratePoint(bool* morePoints, uint32_t timeout) {
+ int result = 0;
+ bool ret = false;
+
+ if (!_initialized) return false;
+
+ do {
+ if (morePoints == NULL || _calibPoint >= AR1021_NUM_CALIB_POINTS) {
+ break;
+ }
+
+ // wait for response
+ result = waitForCalibResponse(timeout);
+ if (result != 0) {
+ debug("wait for calibration response failed (%d)\n", result);
+ break;
+ }
+
+ _calibPoint++;
+ *morePoints = (_calibPoint < AR1021_NUM_CALIB_POINTS);
+
+
+ // no more points -> enable touch
+ if (!(*morePoints)) {
+
+ // wait for calibration data to be written to eeprom
+ // before enabling touch
+ result = waitForCalibResponse(timeout);
+ if (result != 0) {
+ debug("wait for calibration response failed (%d)\n", result);
+ break;
+ }
+
+
+ // clear chip-select since calibration is done;
+// _cs = 1;
+
+ result = cmd(AR1021_CMD_ENABLE_TOUCH, NULL, 0, NULL, 0);
+ if (result != 0) {
+ debug("enable touch failed (%d)\n", result);
+ break;
+ }
+
+ _siqIrq.rise(this, &AR1021I2C::readTouchIrq);
+ }
+
+ ret = true;
+
+ } while (0);
+
+
+
+ if (!ret) {
+ // make sure to set chip-select off in case of an error
+// _cs = 1;
+ // calibration must restart if an error occurred
+ _calibPoint = AR1021_NUM_CALIB_POINTS+1;
+ }
+
+
+
+ return ret;
+}
+
+int AR1021I2C::cmd(char cmd, char* data, int len, char* respBuf, int* respLen,
+ bool setCsOff) {
+
+ int ret = 0;
+ int readLen = (respLen == NULL) ? 0 : *respLen;
+ for (int attempt = 1; attempt <= AR1021_RETRY; attempt++) {
+ if (attempt > 1) {
+ wait_ms(50);
+ }
+
+ // command request
+ // ---------------
+ // 0x00 0x55 len cmd data
+ // 0x00 = protocol command byte
+ // 0x55 = header
+ // len = data length + cmd (1)
+ // data = data to send
+
+ _i2c.start();
+ _i2c.write(AR1021_ADDR); //send write address
+ _i2c.write(0x00);
+ _i2c.write(0x55); //header
+ _i2c.write(len+1); //message length
+ _i2c.write(cmd);
+ for (int i = 0; i < len; i++) {
+ _i2c.write(data[i]);
+ }
+ wait_us(60);
+ _i2c.stop();
+
+ // wait for response (siq goes high when response is available)
+ Timer t;
+ t.start();
+ while(_siq.read() != 1 && t.read_ms() < AR1021_TIMEOUT);
+
+ if (t.read_ms() < AR1021_TIMEOUT) {
+
+ // command response
+ // ---------------
+ // 0x55 len status cmd data
+ // 0x55 = header
+ // len = number of bytes following the len byte (i.e. including the status&cmd)
+ // status = status
+ // cmd = command ID
+ // data = data to receive
+ _i2c.start();
+ _i2c.write(AR1021_ADDR + 1); //send read address
+ char header = _i2c.read(1); //header should always be 0x55
+ if (header != 0x55) {
+ ret = AR1021_ERR_NO_HDR;
+ continue;
+ }
+ char length = _i2c.read(1); //data length
+ if (length < 2) {
+ ret = AR1021_ERR_INV_LEN; //must have at least status and command bytes
+ continue;
+ }
+ length -= 2;
+ if (length > readLen) {
+ ret = AR1021_ERR_INV_LEN; //supplied buffer is not enough
+ continue;
+ }
+
+ char status = _i2c.read(1); //command status
+ char usedCmd;
+ if (readLen <= 0) {
+ usedCmd = _i2c.read(0); //no data => read command byte + NACK
+ } else {
+ usedCmd = _i2c.read(1); //which command
+
+ //we need to send a NACK on the last read.
+ int i;
+ for (i = 0; i < (length-1); i++) {
+ respBuf[i] = _i2c.read(1);
+ }
+ respBuf[i] = _i2c.read(0); //last returned data byte + NACK
+ }
+ _i2c.stop();
+
+
+ if (status != AR1021_RESP_STAT_OK) {
+ ret = -status;
+ continue;
+ }
+ if (usedCmd != cmd) {
+ ret = AR1021_ERR_INV_RESP;
+ continue;
+ }
+
+ // success
+ ret = 0;
+ break;
+
+ } else {
+ ret = AR1021_ERR_TIMEOUT;
+ continue;
+ }
+ }
+
+ return ret;
+}
+
+int AR1021I2C::waitForCalibResponse(uint32_t timeout) {
+ Timer t;
+ int ret = 0;
+
+ t.start();
+
+ // wait for siq
+ while (_siq.read() != 1 &&
+ (timeout == 0 || (uint32_t)t.read_ms() < (int)timeout));
+
+
+ do {
+
+ if (timeout > 0 && (uint32_t)t.read_ms() >= timeout) {
+ ret = AR1021_ERR_TIMEOUT;
+ break;
+ }
+
+ // command response
+ // ---------------
+ // 0x55 len status cmd data
+ // 0x55 = header
+ // len = number of bytes following the len byte (should be 2)
+ // status = status
+ // cmd = command ID
+ _i2c.start();
+ _i2c.write(AR1021_ADDR + 1); //send read address
+ char header = _i2c.read(1); //header should always be 0x55
+ char length = _i2c.read(1); //data length
+
+ if (header != 0x55) {
+ ret = AR1021_ERR_NO_HDR;
+ break;
+ }
+ if (length < 2) {
+ ret = AR1021_ERR_INV_LEN;
+ break;
+ }
+ char status = _i2c.read(1); //status
+ char cmd = _i2c.read(0); //command, should be NACK'ed
+ _i2c.stop();
+ if (status != AR1021_RESP_STAT_OK) {
+ ret = -status;
+ break;
+ }
+ if (cmd != AR1021_CMD_CALIBRATE_MODE) {
+ ret = AR1021_ERR_INV_RESP;
+ break;
+ }
+
+ // success
+ ret = 0;
+
+ } while (0);
+
+ return ret;
+}
+
+
+void AR1021I2C::readTouchIrq() {
+ while(_siq.read() == 1) {
+
+ // touch coordinates are sent in a 5-byte data packet
+ _i2c.start();
+ _i2c.write(AR1021_ADDR + 1); //send read address
+ int pen = _i2c.read(1);
+ int xlo = _i2c.read(1);
+ int xhi = _i2c.read(1);
+ int ylo = _i2c.read(1);
+ int yhi = _i2c.read(0);
+ _i2c.stop();
+
+ // pen down
+ if ((pen&AR1021_PEN_MASK) == (1<<7|1<<0)) {
+ _pen = 1;
+ }
+ // pen up
+ else if ((pen&AR1021_PEN_MASK) == (1<<7)){
+ _pen = 0;
+ }
+ // invalid value
+ else {
+ continue;
+ }
+
+ _x = ((xhi<<7)|xlo);
+ _y = ((yhi<<7)|ylo);
+ }
+}
+
+bool AR1021I2C::info(int* verHigh, int* verLow, int* resBits, int* type)
+{
+ char buff[3] = {0,0,0};
+ int read = 3;
+ int res = cmd(AR1021_CMD_GET_VERSION, NULL, 0, buff, &read);
+ if (res == 0) {
+ *verHigh = buff[0];
+ *verLow = buff[1];
+ switch(buff[2] & 3) {
+ case 0:
+ *resBits = 8;
+ break;
+ case 1:
+ *resBits = 10;
+ break;
+ case 2:
+ *resBits = 12;
+ break;
+ case 3:
+ *resBits = 12;
+ break;
+ default:
+ res = 25;
+ printf("Invalid resolution %d\n", buff[2]&3);
+ break;
+ }
+ *type = buff[2]>>2;
+ }
+ return (res == 0);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/AR1021I2C.h Fri Oct 03 13:37:30 2014 +0000
@@ -0,0 +1,77 @@
+/*
+ * 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 AR1021I2C_H
+#define AR1021I2C_H
+
+#include "TouchPanel.h"
+
+/**
+ * Microchip Touch Screen Controller (AR1021).
+ *
+ * Please note that this touch panel has an on-board storage for
+ * calibration data. Once a successful calibration has been performed
+ * it is not needed to do additional calibrations since the stored
+ * calibration data will be used.
+ */
+class AR1021I2C : public TouchPanel {
+public:
+
+
+ /**
+ * Constructor
+ *
+ * @param mosi I2C SDA pin
+ * @param miso I2C SCL pin
+ * @param siq interrupt pin
+ */
+ AR1021I2C(PinName sda, PinName scl, PinName siq);
+
+ bool info(int* verHigh, int* verLow, int* resBits, int* type);
+
+ virtual bool init(uint16_t width, uint16_t height);
+ virtual bool read(touchCoordinate_t &coord);
+ virtual bool calibrateStart();
+ virtual bool getNextCalibratePoint(uint16_t* x, uint16_t* y);
+ virtual bool waitForCalibratePoint(bool* morePoints, uint32_t timeout);
+
+private:
+
+
+ I2C _i2c;
+ DigitalIn _siq;
+ InterruptIn _siqIrq;
+ bool _initialized;
+
+
+ int32_t _x;
+ int32_t _y;
+ int32_t _pen;
+
+ uint16_t _width;
+ uint16_t _height;
+ uint8_t _inset;
+
+ int _calibPoint;
+
+
+ int cmd(char cmd, char* data, int len, char* respBuf, int* respLen, bool setCsOff=true);
+ int waitForCalibResponse(uint32_t timeout);
+ void readTouchIrq();
+};
+
+#endif
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/EALib.lib Fri Oct 03 13:37:30 2014 +0000 @@ -0,0 +1,1 @@ +https://mbed.org/users/embeddedartists/code/EALib/#b3a179cc3d88
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/EaLcdBoardGPIO.cpp Fri Oct 03 13:37:30 2014 +0000
@@ -0,0 +1,96 @@
+/*
+ * 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 "EaLcdBoardGPIO.h"
+
+/******************************************************************************
+ * Defines and typedefs
+ *****************************************************************************/
+
+
+EaLcdBoardGPIO::EaLcdBoardGPIO(PinName sda, PinName scl)
+ : EaLcdBoard(sda, scl), /*pinWP(P4_15),*/ pin3v3(P2_0), pin5v(P2_21), pinDE(P2_11), pinContrast(P2_1)
+{
+ pinContrast.period_ms(10);
+ setWriteProtect(true);
+ set3V3Signal(false);
+ set5VSignal(false);
+ setDisplayEnableSignal(false);
+ setBacklightContrast(0);
+}
+
+
+void EaLcdBoardGPIO::setWriteProtect(bool enable)
+{
+ // Not Applicable
+}
+
+void EaLcdBoardGPIO::set3V3Signal(bool enabled) { //P2.0 L=3.3V on
+ if (enabled) {
+ pin3v3 = 0;
+ } else {
+ pin3v3 = 1;
+ }
+}
+
+void EaLcdBoardGPIO::set5VSignal(bool enabled) { //P2.21 H=5V on
+ if (enabled) {
+ pin5v = 1;
+ } else {
+ pin5v = 0;
+ }
+}
+
+void EaLcdBoardGPIO::setDisplayEnableSignal(bool enabled) { //P2.11 H=enabled
+ LPC_IOCON->P2_11 &= ~7; /* GPIO2[11] @ P2.11 */
+ if (enabled) {
+ pinDE = 1;
+ } else {
+ pinDE = 0;
+ }
+}
+
+void EaLcdBoardGPIO::setBacklightContrast(uint32_t value) { //P2.1, set to 4.30 for now
+#if 0
+ LPC_IOCON->P2_1 &= ~7; /* GPIO2[1] @ P2.1 */
+ if (value > 50) {
+ pinContrast = 1;
+ } else {
+ pinContrast = 0;
+ }
+#else
+ uint32_t tmp = LPC_IOCON->P2_1;
+ tmp &= ~7;
+ tmp |= 1;
+ LPC_IOCON->P2_1 = tmp; /* PWM2[1] @ P2.1 */
+ float f = value;
+ pinContrast = f/100.0f;
+#endif
+
+// if (value > 100) return;
+
+// pca9532_setBlink0Duty(100-value);
+// pca9532_setBlink0Period(0);
+// pca9532_setBlink0Leds(LCDB_CTRL_BL_C);
+}
+
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/EaLcdBoardGPIO.h Fri Oct 03 13:37:30 2014 +0000
@@ -0,0 +1,50 @@
+/*
+ * 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 EALCDBOARDGPIO_H
+#define EALCDBOARDGPIO_H
+
+#include "EaLcdBoard.h"
+
+/** An interface to Embedded Artists LCD Boards
+ *
+ */
+class EaLcdBoardGPIO : public EaLcdBoard {
+public:
+
+ EaLcdBoardGPIO(PinName sda, PinName scl);
+
+ void setBC(uint32_t val) { setBacklightContrast(val); };
+
+protected:
+ virtual void setWriteProtect(bool enable);
+ virtual void set3V3Signal(bool enabled);
+ virtual void set5VSignal(bool enabled);
+ virtual void setDisplayEnableSignal(bool enabled);
+ virtual void setBacklightContrast(uint32_t value);
+
+private:
+ //DigitalOut pinWP;
+ DigitalOut pin3v3;
+ DigitalOut pin5v;
+ DigitalOut pinDE;
+ //DigitalOut pinContrast;
+ PwmOut pinContrast;
+};
+
+#endif
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Graphics.cpp Fri Oct 03 13:37:30 2014 +0000
@@ -0,0 +1,241 @@
+
+#include "mbed.h"
+#include "Graphics.h"
+
+
+Graphics::Graphics(uint16_t *pFrmBuf, uint16_t dispWidth, uint16_t dispHeight)
+{
+ this->windowX = dispWidth;
+ this->windowY = dispHeight;
+ this->pFrmBuf = pFrmBuf;
+}
+
+void Graphics::setFrameBuffer( uint16_t *pFrmBuf )
+{
+ this->pFrmBuf = pFrmBuf;
+}
+
+int32_t Graphics::abs(int32_t v1) const
+{
+ if (v1 > 0)
+ return v1;
+
+ return -v1;
+}
+
+/***********************************************************************
+ *
+ * Function: swim_put_line_raw
+ *
+ * Purpose: Draw a line on the physical display
+ *
+ * Processing:
+ * See function.
+ *
+ * Parameters:
+ * win : Window identifier
+ * x1 : Physical X position of X line start
+ * y1 : Physical Y position of Y line start
+ * x2 : Physical X position of X line end
+ * y2 : Physical Y position of Y line end
+ *
+ * Outputs: None
+ *
+ * Returns: Nothing
+ *
+ * Notes: None
+ *
+ **********************************************************************/
+void Graphics::put_line(int32_t x1, int32_t y1, int32_t x2, int32_t y2, int16_t color)
+{
+ int32_t e2, sx, sy, dx, dy, err;
+
+ /* calculate delta_x and delta_y */
+ dx = abs(x2 - x1);
+ dy = abs(y2 - y1);
+
+ /* set the direction for the step for both x and y, and
+ initialize the error */
+ if (x1 < x2)
+ sx = 1;
+ else
+ sx = -1;
+
+ if (y1 < y2)
+ sy = 1;
+ else
+ sy = -1;
+
+ err = dx - dy;
+
+ while (1)
+ {
+ if ((x1 >= 0) && (x1 < this->windowX) &&
+ (y1 >= 0) && (y1 < this->windowY))
+ this->pFrmBuf[x1 + (this->windowX*y1)] = color;
+
+ if ((x1 == x2) && (y1 == y2))
+ return;
+
+ e2 = 2 * err;
+ if (e2 > -dy)
+ {
+ err -= dy;
+ x1 += sx;
+ }
+ if (e2 < dx)
+ {
+ err += dx;
+ y1 += sy;
+ }
+ }
+}
+
+/***********************************************************************
+ *
+ * Function: plot4points
+ *
+ * Purpose:
+ *
+ * Processing:
+ * See function.
+ *
+ * Parameters:
+ * win : Window identifier
+ * cx :
+ * cy :
+ * x :
+ * y :
+ * Filled :
+ *
+ * Outputs: None
+ *
+ * Returns: Nothing
+ *
+ * Notes: None
+ *
+ **********************************************************************/
+void Graphics::plot4points( int32_t cx, int32_t cy, int32_t x, int32_t y, int16_t color, int32_t Filled )
+ {
+ int16_t x0, x1, y0, y1;
+
+ y0 = cy + y;
+ y1 = cy - y;
+ if( Filled )
+ {
+ for( x0=cx - x; x0<=cx + x; x0++ )
+ {
+ if ((x0>=0) && (x0<this->windowX) && (y0>=0) && (y0<this->windowY))
+ this->pFrmBuf[x0 + (this->windowX*y0)] = color;
+ if ((x0>=0) && (x0<this->windowX) && (y1>=0) && (y1<this->windowY))
+ this->pFrmBuf[x0 + (this->windowX*y1)] = color;
+ }
+ }
+ else
+ {
+ x0 = cx + x;
+ x1 = cx - x;
+ if ((x0>=0) && (x0<this->windowX) && (y0>=0) && (y0<this->windowY))
+ this->pFrmBuf[x0 + (this->windowX*y0)] = color;
+ if ((x != 0) &&
+ (x1>=0) && (x1<this->windowX) && (y0>=0) && (y0<this->windowY))
+ this->pFrmBuf[x1 + (this->windowX*y0)] = color;
+ if ((y != 0) &&
+ (x0>=0) && (x0<this->windowX) && (y1>=0) && (y1<this->windowY))
+ this->pFrmBuf[x0 + (this->windowX*y1)] = color;
+ if ((x != 0 && y != 0) &&
+ (x1>=0) && (x1<this->windowX) && (y1>=0) && (y1<this->windowY))
+ this->pFrmBuf[x1 + (this->windowX*y1)] = color;
+ }
+ }
+
+/***********************************************************************
+ *
+ * Function: plot8points
+ *
+ * Purpose:
+ *
+ * Processing:
+ * See function.
+ *
+ * Parameters:
+ * win : Window identifier
+ * cx :
+ * cy :
+ * x :
+ * y :
+ * Filled :
+ *
+ * Outputs: None
+ *
+ * Returns: Nothing
+ *
+ * Notes: None
+ *
+ **********************************************************************/
+void Graphics::plot8points( int32_t cx, int32_t cy, int32_t x, int32_t y, int16_t color, int32_t Filled )
+ {
+ plot4points( cx, cy, x, y, color, Filled );
+ if (x != y)
+ plot4points( cx, cy, y, x, color, Filled );
+ }
+
+/***********************************************************************
+ *
+ * Function: swim_put_circle
+ *
+ * Purpose:
+ *
+ * Processing:
+ * See function.
+ *
+ * Parameters:
+ * win : Window identifier
+ * cx :
+ * cy :
+ * radius :
+ * Filled :
+ *
+ * Outputs: None
+ *
+ * Returns: Nothing
+ *
+ * Notes: None
+ *
+ **********************************************************************/
+void Graphics::put_circle( int32_t cx, int32_t cy, int16_t color, int32_t radius, int32_t Filled )
+ {
+ int32_t Error = -radius;
+ int16_t x = radius;
+ int16_t y = 0;
+
+ while( x >= y )
+ {
+ plot8points( cx, cy, x, y, color, Filled );
+
+ Error += y;
+ ++y;
+ Error += y;
+
+ if( Error >= 0 )
+ {
+ --x;
+ Error -= x;
+ Error -= x;
+ }
+ }
+ }
+
+void Graphics::put_dot( int32_t cx, int32_t cy, int16_t color )
+{
+ int size = 1;
+ for (int y1 = cy - size; y1 <= (cy + size); y1++) {
+ for (int x1 = cx - size; x1 <= (cx + size); x1++) {
+ if ((x1 >= 0) && (x1 < this->windowX) && (y1 >= 0) && (y1 < this->windowY)) {
+ this->pFrmBuf[x1 + (this->windowX*y1)] = color;
+ }
+ }
+ }
+}
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Graphics.h Fri Oct 03 13:37:30 2014 +0000
@@ -0,0 +1,29 @@
+
+#ifndef GRAPHICS_H
+#define GRAPHICS_H
+
+class Graphics {
+public:
+
+ Graphics(uint16_t *pFrmBuf, uint16_t dispWidth, uint16_t dispHeight);
+
+ void setFrameBuffer( uint16_t *pFrmBuf );
+ void put_line(int32_t x1, int32_t y1, int32_t x2, int32_t y2, int16_t color);
+ void put_circle( int32_t cx, int32_t cy, int16_t color, int32_t radius, int32_t Filled );
+ void put_dot( int32_t cx, int32_t cy, int16_t color );
+
+protected:
+ uint16_t windowX;
+ uint16_t windowY;
+ uint16_t *pFrmBuf;
+
+ int32_t abs(int32_t v1) const;
+
+ virtual void plot4points( int32_t cx, int32_t cy, int32_t x, int32_t y, int16_t color, int32_t Filled );
+ void plot8points( int32_t cx, int32_t cy, int32_t x, int32_t y, int16_t color, int32_t Filled );
+
+};
+
+#endif
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/TestDisplay.cpp Fri Oct 03 13:37:30 2014 +0000
@@ -0,0 +1,216 @@
+/*
+ * 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"
+
+#include "WaveDemo.h"
+
+/******************************************************************************
+ * Defines and typedefs
+ *****************************************************************************/
+
+#define LCD_CONFIGURATION_43 \
+ 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_43 (char*)"v1,cd0,c50,cc0,c30,d100,c31,d100,cd1,d10,o,c51,cc100"
+
+#define LCD_CONFIGURATION_50 \
+ 46, /* horizontalBackPorch */ \
+ 20, /* horizontalFrontPorch */ \
+ 2, /* hsync */ \
+ 800, /* width */ \
+ 23, /* verticalBackPorch */ \
+ 10, /* verticalFrontPorch */ \
+ 3, /* vsync */ \
+ 480, /* height */ \
+ false, /* invertOutputEnable */ \
+ false, /* invertPanelClock */ \
+ true, /* invertHsync */ \
+ true, /* invertVsync */ \
+ 1, /* acBias */ \
+ LcdController::Bpp_16_565, /* bpp */ \
+ 30000000, /* optimalClock */ \
+ LcdController::Tft, /* panelType */ \
+ false /* dualPanel */
+
+#define LCD_INIT_STRING_50 (char*)"v1,cc0,c31,d50,o,d200,c51,cc100"
+
+#define MY_ABS(__a) (((__a) < 0) ? -(__a) : (__a))
+
+/******************************************************************************
+ * 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
+
+*/
+
+TestDisplay::TestDisplay(WhichDisplay which) :
+ _initStr(NULL),
+ _lcdCfg(NULL),
+ _lcdBoard(P0_27, P0_28),
+ _touch(P0_27, P0_28, P2_25) {
+
+ switch (which) {
+ case TFT_5:
+ _lcdCfg = new LcdController::Config(LCD_CONFIGURATION_50);
+ _initStr = LCD_INIT_STRING_50;
+ break;
+ case TFT_4_3:
+ _lcdCfg = new LcdController::Config(LCD_CONFIGURATION_43);
+ _initStr = LCD_INIT_STRING_43;
+ break;
+ default:
+ mbed_die();
+ }
+
+ if (sdram_init() == 1) {
+ printf("Failed to initialize SDRAM\n");
+ _framebuffer = 0;
+ } else {
+ _framebuffer = (uint32_t) malloc(_lcdCfg->width * _lcdCfg->height * 2 * 3); // 2 is for 16 bit color, 3 is the number of buffers
+ if (_framebuffer != 0) {
+ memset((uint8_t*)_framebuffer, 0, _lcdCfg->width * _lcdCfg->height * 2 * 3);
+ }
+ }
+}
+
+TestDisplay::~TestDisplay() {
+ if (_framebuffer != 0) {
+ free((void*)_framebuffer);
+ _framebuffer = 0;
+ }
+}
+
+bool TestDisplay::runTest() {
+ do {
+ if (_framebuffer == 0) {
+ printf("Failed to allocate memory for framebuffer\n");
+ break;
+ }
+
+ EaLcdBoard::Result result = _lcdBoard.open(_lcdCfg, _initStr);
+ 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;
+ }
+
+ WaveDemo waveDemo((uint8_t *)_framebuffer, _lcdCfg->width, _lcdCfg->height);
+ while (1) {
+ waveDemo.run(_lcdBoard, 750, 50);
+ }
+ } while(0);
+
+ return false;
+}
+
+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 5999 seconds
+ Timer t;
+ t.start();
+ TouchPanel::touchCoordinate_t tc;
+ while(t.read() < 6000) {
+ 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;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/TestDisplay.h Fri Oct 03 13:37:30 2014 +0000
@@ -0,0 +1,63 @@
+/*
+ * 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 TESTDISPLAY_H
+#define TESTDISPLAY_H
+
+#include "AR1021I2C.h"
+#include "Graphics.h"
+#include "LcdController.h"
+#include "EaLcdBoardGPIO.h"
+
+/**
+ * Test the display connected with a FPC cable to the LPC4088 Experiment Base Board
+ * as well as the AR1021 touch sensor on the board.
+ */
+class TestDisplay {
+public:
+ enum WhichDisplay {
+ TFT_5, // 5" display
+ TFT_4_3, // 4.3" display
+ };
+
+ /**
+ * Create an interface to the display
+ */
+ TestDisplay(WhichDisplay which);
+ ~TestDisplay();
+
+ /**
+ * Test the display
+ *
+ * @return true if the test was successful; otherwise false
+ */
+ bool runTest();
+
+private:
+
+ void calibrate_drawMarker(Graphics &g, uint16_t x, uint16_t y, bool erase);
+ bool calibrate_display();
+
+ char* _initStr;
+ LcdController::Config* _lcdCfg;
+ EaLcdBoardGPIO _lcdBoard;
+ AR1021I2C _touch;
+
+ uint32_t _framebuffer;
+};
+
+#endif
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/WaveDemo.cpp Fri Oct 03 13:37:30 2014 +0000
@@ -0,0 +1,295 @@
+/******************************************************************************
+ * Includes
+ *****************************************************************************/
+
+#include "mbed.h"
+
+#include "LcdController.h"
+#include "EaLcdBoard.h"
+#include "WaveDemo.h"
+
+#include <math.h>
+
+/******************************************************************************
+ * Typedefs and defines
+ *****************************************************************************/
+
+#define PI2 6.283185307179586476925286766559
+
+/* 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
+ *****************************************************************************/
+
+uint16_t WaveDemo::fastsqrt(uint32_t n) const {
+ uint16_t c = 0x8000;
+ uint16_t g = 0x8000;
+ for(;;) {
+ if(g*g > n)
+ g ^= c;
+ c >>= 1;
+ if(c == 0)
+ return g;
+ g |= c;
+ }
+}
+
+void WaveDemo::matrix(int16_t xyz[3][N], uint8_t rgb[3][N]) {
+ static uint32_t t = 0;
+ uint16_t i;
+ int16_t x = -SCALE;
+ int16_t y = -SCALE;
+ uint16_t d;
+ uint16_t s;
+
+ for(i = 0; i < N; i++) {
+
+ xyz[0][i] = x;
+ xyz[1][i] = y;
+
+ d = fastsqrt(x * x + y * y);
+ s = sine[(t * 30) % SCALE] + SCALE;
+
+ xyz[2][i] = sine[(d + s) % SCALE] *
+ sine[(t * 10) % SCALE] / SCALE / 2;
+
+ rgb[0][i] = (cosi[xyz[2][i] + SCALE / 2] + SCALE) *
+ (RED_COLORS - 1) / SCALE / 2;
+
+ rgb[1][i] = (cosi[(xyz[2][i] + SCALE / 2 + 2 * SCALE / 3) % SCALE] + SCALE) *
+ (GREEN_COLORS - 1) / SCALE / 2;
+
+ rgb[2][i] = (cosi[(xyz[2][i] + SCALE / 2 + SCALE / 3) % SCALE] + SCALE) *
+ (BLUE_COLORS - 1) / SCALE / 2;
+
+ x += INCREMENT;
+ if(x >= SCALE) {
+ x = -SCALE;
+ y += INCREMENT;
+ }
+
+ }
+ t++;
+}
+
+void WaveDemo::rotate(int16_t xyz[3][N], uint8_t rgb[3][N],
+ uint16_t angleX, uint16_t angleY, uint16_t angleZ) {
+ uint16_t i;
+ int16_t tmpX;
+ int16_t tmpY;
+ int16_t sinx = sine[angleX];
+ int16_t cosx = cosi[angleX];
+ int16_t siny = sine[angleY];
+ int16_t cosy = cosi[angleY];
+ int16_t sinz = sine[angleZ];
+ int16_t cosz = cosi[angleZ];
+
+ for(i = 0; i < N; i++) {
+ tmpX = (xyz[0][i] * cosx - xyz[2][i] * sinx) / SCALE;
+ xyz[2][i] = (xyz[0][i] * sinx + xyz[2][i] * cosx) / SCALE;
+ xyz[0][i] = tmpX;
+
+ tmpY = (xyz[1][i] * cosy - xyz[2][i] * siny) / SCALE;
+ xyz[2][i] = (xyz[1][i] * siny + xyz[2][i] * cosy) / SCALE;
+ xyz[1][i] = tmpY;
+
+ tmpX = (xyz[0][i] * cosz - xyz[1][i] * sinz) / SCALE;
+ xyz[1][i] = (xyz[0][i] * sinz + xyz[1][i] * cosz) / SCALE;
+ xyz[0][i] = tmpX;
+ }
+}
+
+void WaveDemo::draw(int16_t xyz[3][N], uint8_t rgb[3][N]) {
+// static uint16_t oldProjX[N] = {0};
+// static uint16_t oldProjY[N] = {0};
+// static uint8_t oldDotSize[N] = {0};
+ uint16_t i;
+ uint16_t projX;
+ uint16_t projY;
+ uint16_t projZ;
+ uint16_t dotSize;
+ static uint8_t cnt=0;
+
+ if (cnt == 0)
+ {
+ cnt = 1;
+ pFrmBuf = pFrmBuf1;
+ }
+ else if (cnt == 1)
+ {
+ cnt = 2;
+ pFrmBuf = pFrmBuf2;
+ }
+ else
+ {
+ cnt = 0;
+ pFrmBuf = pFrmBuf3;
+ }
+
+ graphics.setFrameBuffer(pFrmBuf);
+
+ memset((void*)(pFrmBuf), 0x00, windowX * windowY * 2);
+
+ for(i = 0; i < N; i++) {
+ projZ = SCALE - (xyz[2][i] + SCALE) / 4; //4;
+ projX = windowX / 2 + (xyz[0][i] * projZ / SCALE) / 40; //EA 25;
+ projY = windowY / 2 + (xyz[1][i] * projZ / SCALE) / 40; //EA 25;
+ dotSize = 3 - (xyz[2][i] + SCALE) * 2 / SCALE;
+//EA put_circle(oldProjX[i], oldProjY[i], 0, dotSize, 1);
+
+ if((projX > dotSize) &&
+ (projY > dotSize) &&
+ (projX < (windowX - dotSize)) &&
+ (projY < (windowY - dotSize))) {
+
+ graphics.put_circle(projX, projY, (rgb[0][i] << REDSHIFT) + (rgb[1][i] << GREENSHIFT) + (rgb[2][i] << BLUESHIFT), dotSize, 1);
+
+// oldProjX[i] = projX;
+// oldProjY[i] = projY;
+// oldDotSize[i] = dotSize;
+ }
+ }
+}
+
+
+
+/******************************************************************************
+ * Public functions
+ *****************************************************************************/
+WaveDemo::WaveDemo(uint8_t *pFrameBuf, uint16_t dispWidth, uint16_t dispHeight)
+ : graphics((uint16_t *)pFrameBuf, dispWidth, dispHeight)
+{
+ this->windowX = dispWidth;
+ this->windowY = dispHeight;
+ this->pFrmBuf = (uint16_t *)pFrameBuf;
+ this->pFrmBuf1 = (uint16_t *)pFrameBuf;
+ this->pFrmBuf2 = (uint16_t *)((uint32_t)pFrameBuf + dispWidth*dispHeight*2);
+ this->pFrmBuf3 = (uint16_t *)((uint32_t)pFrameBuf + dispWidth*dispHeight*4);
+
+ for(uint16_t i = 0; i < SCALE; i++) {
+ sine[i] = (int)(sin(PI2 * i / SCALE) * SCALE);
+ cosi[i] = (int)(cos(PI2 * i / SCALE) * SCALE);
+ }
+}
+
+void WaveDemo::run(EaLcdBoardGPIO& lcdBoard, uint32_t loops, uint32_t delayMs)
+{
+ printf("WaveDemo, %d loops, %dms delay\n", loops, delayMs);
+
+ int16_t angleX = 0;
+ int16_t angleY = 1000;
+ int16_t angleZ = 0;
+
+ int16_t speedX = 0;
+ int16_t speedY = 0;
+ int16_t speedZ = 0;
+
+ int16_t xyz[3][N];
+ uint8_t rgb[3][N];
+
+ loops = 2*820;
+ for(int32_t n=0;n<loops;n++) {
+
+ matrix(xyz, rgb);
+
+ rotate(xyz, rgb, angleX, angleY, angleZ);
+
+ draw(xyz, rgb);
+ //update framebuffer
+ lcdBoard.setFrameBuffer((uint32_t)this->pFrmBuf);
+
+#if 0
+ if(joyState & JOYSTICK_RIGHT)
+ speedX -= SPEED;
+ else if(joyState & JOYSTICK_LEFT)
+ speedX += SPEED;
+ else if(joyState & JOYSTICK_UP)
+ speedY -= SPEED;
+ else if(joyState & JOYSTICK_DOWN)
+ speedY += SPEED;
+ else if(ledState & KEY1)
+ speedZ -= SPEED;
+ else if(ledState & KEY2)
+ speedZ += SPEED;
+ else if(ledState & KEY3) {
+ speedX = 0;
+ speedY = 0;
+ speedZ = 0;
+ angleX = 0;
+ angleY = 0;
+ angleZ = 0;
+ } else
+#endif
+ {
+ if(speedX > 0)
+ speedX -= SPEED;
+ else if(speedX < 0)
+ speedX += SPEED;
+
+ if(speedY > 0)
+ speedY -= SPEED;
+ else if(speedY < 0)
+ speedY += SPEED;
+
+ if(speedZ > 0)
+ speedZ -= SPEED;
+ else if(speedZ < 0)
+ speedZ += SPEED;
+ }
+
+ angleX += 0; //speedX;
+ angleY += 0; //speedY;
+ angleZ += 2; //speedZ;
+
+ if(angleX >= SCALE)
+ angleX -= SCALE;
+ else if(angleX < 0)
+ angleX += SCALE;
+
+ if(angleY >= SCALE)
+ angleY -= SCALE;
+ else if(angleY < 0)
+ angleY += SCALE;
+
+ if(angleZ >= SCALE)
+ angleZ -= SCALE;
+ else if(angleZ < 0)
+ angleZ += SCALE;
+
+ }
+//wait_ms(delayMs);
+ wait_ms(1000);
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/WaveDemo.h Fri Oct 03 13:37:30 2014 +0000
@@ -0,0 +1,63 @@
+
+#ifndef WAVEDEMO_H
+#define WAVEDEMO_H
+
+#include "Graphics.h"
+#include "GFXFb.h"
+
+#include "EaLcdBoardGPIO.h"
+
+class WaveDemo {
+public:
+
+ /** 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
+ */
+ WaveDemo(uint8_t *pFrameBuf, uint16_t dispWidth, uint16_t dispHeight);
+
+ void run(EaLcdBoardGPIO& lcdBoard, uint32_t loops, uint32_t delayMs);
+
+private:
+
+ enum Constants {
+ N = 1024, // Number of dots
+ SCALE = 8192,
+ INCREMENT = 512, // INCREMENT = SCALE / sqrt(N) * 2
+ SPEED = 5
+ };
+
+ int32_t windowX;
+ int32_t windowY;
+ uint16_t *pFrmBuf;
+ uint16_t *pFrmBuf1;
+ uint16_t *pFrmBuf2;
+ uint16_t *pFrmBuf3;
+
+ Graphics graphics;
+
+ int16_t sine[SCALE];
+ int16_t cosi[SCALE];
+
+ uint16_t fastsqrt(uint32_t n) const;
+ void matrix(int16_t xyz[3][N], uint8_t rgb[3][N]);
+ void rotate(int16_t xyz[3][N], uint8_t rgb[3][N], uint16_t angleX, uint16_t angleY, uint16_t angleZ);
+ void draw(int16_t xyz[3][N], uint8_t rgb[3][N]);
+};
+
+#endif /* WAVEDEMO_H */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Fri Oct 03 13:37:30 2014 +0000
@@ -0,0 +1,46 @@
+/******************************************************************************
+ * Includes
+ *****************************************************************************/
+#include "mbed.h"
+
+#include "TestDisplay.h"
+
+/******************************************************************************
+ * Typedefs and defines
+ *****************************************************************************/
+
+
+/******************************************************************************
+ * Local variables
+ *****************************************************************************/
+
+DigitalOut myled(LED1);
+
+/******************************************************************************
+ * Local functions
+ *****************************************************************************/
+
+/*
+ * Test program for the 4.3" and 5" displays. This test is supposed to run
+ * on a LPC4088QSB board on an LPC4088 Experiment Base Board.
+ */
+
+
+int main() {
+ printf("\n"
+ "---\n"
+ "Display Demo Program for 4.3 and 5 inch display on the LPC4088 Experiment Base Board\n"
+ "Build Date: " __DATE__ " at " __TIME__ "\n"
+ "\n");
+
+ //TestDisplay display(TestDisplay::TFT_4_3);
+ TestDisplay display(TestDisplay::TFT_5);
+ display.runTest();
+
+ while(1) {
+ myled = 1;
+ wait(0.2);
+ myled = 0;
+ wait(0.2);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Fri Oct 03 13:37:30 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/552587b429a1 \ No newline at end of file