Small changes
Dependencies: FATFileSystem
Fork of EALib by
Revision 4:b32cf4ef45c5, committed 2013-10-18
- Comitter:
- embeddedartists
- Date:
- Fri Oct 18 12:48:58 2013 +0200
- Parent:
- 3:9d31a3c5013e
- Child:
- 5:3290d7b766d5
- Commit message:
- Added AR1021 touch controller
Added MMA7455 accelerometer
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/AR1021.cpp Fri Oct 18 12:48:58 2013 +0200 @@ -0,0 +1,526 @@ + +/****************************************************************************** + * Includes + *****************************************************************************/ + +#include "mbed.h" +#include "mbed_debug.h" + +#include "AR1021.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) + +AR1021::AR1021(PinName mosi, PinName miso, PinName sck, PinName cs, PinName siq) : +_spi(mosi, miso, sck), _cs(cs), _siq(siq), _siqIrq(siq) +{ + _cs = 1; // active low + + _spi.format(8, 1); + _spi.frequency(500000); + + // 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 AR1021::read(touchCoordinate_t &coord) { + + if (!_initialized) return false; + + coord.x = _x * _width/4095; + coord.y = _y * _height/4095; + coord.z = _pen; + + return true; +} + + +bool AR1021::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, &AR1021::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 AR1021::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 AR1021::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 AR1021::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, &AR1021::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 AR1021::cmd(char cmd, char* data, int len, char* respBuf, int* respLen, + bool setCsOff) { + + int ret = 0; + + // command request + // --------------- + // 0x55 len cmd data + // 0x55 = header + // len = data length + cmd (1) + // data = data to send + + _cs = 0; + + _spi.write(0x55); + wait_us(50); // according to data sheet there must be an inter-byte delay of ~50us + _spi.write(len+1); + wait_us(50); + _spi.write(cmd); + wait_us(50); + + for(int i = 0; i < len; i++) { + _spi.write(data[i]); + wait_us(50); + } + + + // wait for response (siq goes high when response is available) + Timer t; + t.start(); + while(_siq.read() != 1 && t.read_ms() < 1000); + + + // command response + // --------------- + // 0x55 len status cmd data + // 0x55 = header + // len = number of bytes following the len byte + // status = status + // cmd = command ID + // data = data to receive + + + do { + + if (t.read_ms() >= 1000) { + ret = AR1021_ERR_TIMEOUT; + break; + } + + int head = _spi.write(0); + if (head != 0x55) { + ret = AR1021_ERR_NO_HDR; + break; + } + + wait_us(50); + int len = _spi.write(0); + if (len < 2) { + ret = AR1021_ERR_INV_LEN; + break; + } + + wait_us(50); + int status = _spi.write(0); + if (status != AR1021_RESP_STAT_OK) { + ret = -status; + break; + } + + wait_us(50); + int cmdId = _spi.write(0); + if (cmdId != cmd) { + ret = AR1021_ERR_INV_RESP; + break; + } + + if ( ((len-2) > 0 && respLen == NULL) + || ((len-2) > 0 && respLen != NULL && *respLen < (len-2))) { + ret = AR1021_ERR_INV_RESPLEN; + break; + } + + for (int i = 0; i < len-2;i++) { + wait_us(50); + respBuf[i] = _spi.write(0); + } + if (respLen != NULL) { + *respLen = len-2; + } + + // make sure we wait 50us before issuing a new cmd + wait_us(50); + + } while (0); + + + + // disable chip-select if setCsOff is true or if an error occurred + if (setCsOff || ret != 0) { + _cs = 1; + } + + + + return ret; +} + +int AR1021::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; + } + + int head = _spi.write(0); + if (head != 0x55) { + ret = AR1021_ERR_NO_HDR; + break; + } + + wait_us(50); + int len = _spi.write(0); + if (len != 2) { + ret = AR1021_ERR_INV_LEN; + break; + } + + wait_us(50); + int status = _spi.write(0); + if (status != AR1021_RESP_STAT_OK) { + ret = -status; + break; + } + + wait_us(50); + int cmdId = _spi.write(0); + if (cmdId != 0x14) { + ret = AR1021_ERR_INV_RESP; + break; + } + + + // make sure we wait 50us before issuing a new cmd + wait_us(50); + + } while (0); + + + return ret; +} + + +void AR1021::readTouchIrq() { + while(_siq.read() == 1) { + + _cs = 0; + + // touch coordinates are sent in a 5-byte data packet + + int pen = _spi.write(0); + wait_us(50); + + int xlo = _spi.write(0); + wait_us(50); + + int xhi = _spi.write(0); + wait_us(50); + + int ylo = _spi.write(0); + wait_us(50); + + int yhi = _spi.write(0); + wait_us(50); + + _cs = 1; + + + // 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); + + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/AR1021.h Fri Oct 18 12:48:58 2013 +0200 @@ -0,0 +1,65 @@ + +#ifndef AR1021_H +#define AR1021_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 AR1021 : public TouchPanel { +public: + + + /** + * Constructor + * + * @param mosi SPI MOSI pin + * @param miso SPI MISO pin + * @param sck SPI SCK pin + * @param cs chip-select pin + * @param siq interrupt pin + */ + AR1021(PinName mosi, PinName miso, PinName sck, PinName cs, PinName siq); + + + bool init(uint16_t width, uint16_t height); + bool read(touchCoordinate_t &coord); + bool calibrateStart(); + bool getNextCalibratePoint(uint16_t* x, uint16_t* y); + bool waitForCalibratePoint(bool* morePoints, uint32_t timeout); + +private: + + + SPI _spi; + DigitalOut _cs; + 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
--- a/EaLcdBoard.cpp Wed Oct 09 07:51:52 2013 +0000 +++ b/EaLcdBoard.cpp Fri Oct 18 12:48:58 2013 +0200 @@ -1,7 +1,17 @@ + +/****************************************************************************** + * Includes + *****************************************************************************/ #include "mbed.h" #include "EaLcdBoard.h" +/****************************************************************************** + * Defines and typedefs + *****************************************************************************/ + +#define PORT_PIN_BUG_IN_MBED_SDK + #define LCDB_MAGIC 0xEA01CDAE @@ -38,7 +48,7 @@ /* * Set which sequence string version that is supported */ -#define LCDB_SEQ_VER 1 +#define LCDB_SEQ_VER 2 #ifndef MIN #define MIN(x, y) (((x)<(y))?(x):(y)) @@ -163,6 +173,10 @@ nxp_lcd_param_t lcdParam; + if (cfg == NULL) { + return InvalidArgument; + } + getStore(&h); if (h.magic != LCDB_MAGIC) { @@ -196,6 +210,10 @@ EaLcdBoard::Result EaLcdBoard::getDisplayName(char* buf, int len) { store_t h; + if (buf == NULL) { + return InvalidArgument; + } + getStore(&h); if (h.magic != LCDB_MAGIC) { @@ -214,6 +232,10 @@ EaLcdBoard::Result EaLcdBoard::getDisplayMfg(char* buf, int len) { store_t h; + if (buf == NULL) { + return InvalidArgument; + } + getStore(&h); if (h.magic != LCDB_MAGIC) { @@ -232,6 +254,10 @@ EaLcdBoard::Result EaLcdBoard::getInitSeq(char* buf, int len) { store_t h; + if (buf == NULL) { + return InvalidArgument; + } + getStore(&h); if (h.magic != LCDB_MAGIC) { @@ -251,6 +277,10 @@ EaLcdBoard::Result EaLcdBoard::getPowerDownSeq(char* buf, int len) { store_t h; + if (buf == NULL) { + return InvalidArgument; + } + getStore(&h); if (h.magic != LCDB_MAGIC) { @@ -267,6 +297,93 @@ return Ok; } +EaLcdBoard::Result EaLcdBoard::getTouchParameters(TouchParams_t* params) { + store_t h; + + if (params == NULL) { + return InvalidArgument; + } + + getStore(&h); + + if (h.magic != LCDB_MAGIC) { + return InvalidStorage; + } + + + if (eepromRead((uint8_t*)params, h.tsOff, + (h.end-h.tsOff)) == -1) { + return InvalidStorage; + } + + + if (params->panelId <= TouchPanelInvalidFirst + || params->panelId >= TouchPanelInvalidLast) { + params->panelId = TouchPanelUnknown; + } + + + return Ok; +} + +EaLcdBoard::Result EaLcdBoard::storeParameters( + const char* lcdName, + const char* lcdMfg, + LcdController::Config* cfg, + const char* initSeqStr, + const char* pdSeqStr, + TouchParams_t* touch, + bool controlWp) +{ + store_t h; + nxp_lcd_param_t lcdParam; + + if (lcdName == NULL || lcdMfg == NULL || cfg == NULL + || initSeqStr == NULL || pdSeqStr == NULL) { + return InvalidArgument; + + } + + + lcdParam.h_back_porch = cfg->horizontalBackPorch; + lcdParam.h_front_porch = cfg->horizontalFrontPorch; + lcdParam.h_sync_pulse_width = cfg->hsync; + lcdParam.pixels_per_line = cfg->width; + lcdParam.v_back_porch = cfg->verticalBackPorch; + lcdParam.v_front_porch = cfg->verticalFrontPorch; + lcdParam.v_sync_pulse_width = cfg->vsync; + lcdParam.lines_per_panel = cfg->height; + lcdParam.invert_output_enable = (cfg->invertOutputEnable ? 1 : 0); + lcdParam.invert_panel_clock = (cfg->invertPanelClock ? 1 : 0); + lcdParam.invert_hsync = (cfg->invertHsync ? 1 : 0); + lcdParam.invert_vsync = (cfg->invertVsync ? 1 : 0); + lcdParam.ac_bias_frequency = cfg->acBias; + lcdParam.optimal_clock = cfg->optimalClock; + lcdParam.lcd_panel_type = (nxp_lcd_panel_t)cfg->panelType; + lcdParam.dual_panel = (cfg->dualPanel ? 1 : 0); + + + h.magic = LCDB_MAGIC; + strncpy((char*)h.lcd_name, lcdName, 30); + strncpy((char*)h.lcd_mfg, lcdMfg, 30); + + h.lcdParamOff = sizeof(store_t); + h.initOff = h.lcdParamOff + sizeof(nxp_lcd_param_t); + h.pdOff = h.initOff + strlen(initSeqStr)+1; + h.tsOff = h.pdOff + strlen(pdSeqStr)+1; + h.end = h.tsOff + sizeof(TouchParams_t); + + if (controlWp) setWriteProtect(false); + eepromWrite((uint8_t*)&h, 0, h.lcdParamOff); + eepromWrite((uint8_t*)&lcdParam, h.lcdParamOff, (h.initOff-h.lcdParamOff)); + eepromWrite((uint8_t*)initSeqStr, h.initOff, (h.pdOff-h.initOff)); + eepromWrite((uint8_t*)pdSeqStr, h.pdOff, (h.tsOff-h.pdOff)); + eepromWrite((uint8_t*)touch, h.tsOff, (h.end-h.tsOff)); + if (controlWp) setWriteProtect(true); + + return Ok; +} + EaLcdBoard::Result EaLcdBoard::getStore(store_t* store) { int num = 0; @@ -287,19 +404,26 @@ int EaLcdBoard::eepromRead(uint8_t* buf, uint16_t offset, uint16_t len) { int i = 0; char off[2]; + uint16_t retLen = 0; if (len > LCDB_EEPROM_TOTAL_SIZE || offset+len > LCDB_EEPROM_TOTAL_SIZE) { return -1; } + wait_ms(10); + off[0] = ((offset >> 8) & 0xff); off[1] = (offset & 0xff); - _i2c.write(LCDB_EEPROM_I2C_ADDR, (char*)off, 2); - for ( i = 0; i < 0x2000; i++); - _i2c.read(LCDB_EEPROM_I2C_ADDR, (char*)buf, len); + do { + if (_i2c.write(LCDB_EEPROM_I2C_ADDR, (char*)off, 2) != 0) break; + for ( i = 0; i < 0x2000; i++); + if (_i2c.read(LCDB_EEPROM_I2C_ADDR, (char*)buf, len) != 0) break; - return len; + retLen = len; + } while(0); + + return retLen; } int EaLcdBoard::eepromWrite(uint8_t* buf, uint16_t offset, uint16_t len) { @@ -312,6 +436,8 @@ return -1; } + wait_ms(1); + wLen = LCDB_EEPROM_PAGE_SIZE - (off % LCDB_EEPROM_PAGE_SIZE); wLen = MIN(wLen, len); @@ -319,11 +445,11 @@ tmp[0] = ((off >> 8) & 0xff); tmp[1] = (off & 0xff); memcpy(&tmp[2], (void*)&buf[written], wLen); - _i2c.write(LCDB_EEPROM_I2C_ADDR, (char*)tmp, wLen+2); + if (_i2c.write(LCDB_EEPROM_I2C_ADDR, (char*)tmp, wLen+2) != 0) break; // delay to wait for a write cycle //eepromDelay(); - wait_ms(1); + wait_ms(10); len -= wLen; written += wLen; @@ -400,6 +526,11 @@ break; + // exec pin set + case 'p': + execPinSet(c, len-1); + break; + } if (result != Ok) { @@ -457,6 +588,54 @@ return Ok; } +#ifdef PORT_PIN_BUG_IN_MBED_SDK +static PinName port_pin2(PortName port, int pin_n) { + return (PinName)(((port << 5) | pin_n)); +} +#endif + + +EaLcdBoard::Result EaLcdBoard::execPinSet(char* cmd, uint32_t len) { + + PortName port; + + do { + // cmd: 0_02=1 means p0.2 = 1 + if (len < 6) break; + if (cmd[1] != '_' || cmd[4] != '=') break; + + // port + int portnum = cmd[0] - '0'; + if (portnum < 0 || portnum > 5) break; + port = (PortName)portnum; + + // pin + int pinnum = (10*(cmd[2]-'0'))+ cmd[3]-'0'; + if (pinnum < 0 || pinnum > 31) break; + + // value + int value = cmd[5]-'0'; + if (!(value == 0 || value == 1)) break; + +#ifdef PORT_PIN_BUG_IN_MBED_SDK + PinName pin = port_pin2(port, pinnum); +#else + PinName pin = port_pin(port, pinnum); +#endif + + gpio_t gp; + gpio_init(&gp, pin, PIN_OUTPUT); + gpio_write(&gp, value); + + return Ok; + + } while (false); + + + return InvalidCommandString; +} + + // ########################### // PCA9532 is used as a control inteface to the display. // voltages can be turned on/off and backlight can be controlled. @@ -549,6 +728,15 @@ setLeds(); } +void EaLcdBoard::setWriteProtect(bool enable) +{ + if (enable) { + pca9532_setLeds(0, LCDB_EEPROM_WP); + } else { + pca9532_setLeds(LCDB_EEPROM_WP, 0); + } +} + void EaLcdBoard::set3V3Signal(bool enabled) { if (enabled) { pca9532_setLeds(LCDB_CTRL_3V3, 0); @@ -598,5 +786,3 @@ } - -
--- a/EaLcdBoard.h Wed Oct 09 07:51:52 2013 +0000 +++ b/EaLcdBoard.h Fri Oct 18 12:48:58 2013 +0200 @@ -24,6 +24,30 @@ NameBufferSize = 30 }; + enum TouchPanelId { + // must be first + TouchPanelInvalidFirst = 0x80, + + // Texas Instruments Touch Screen Controller (TSC2046). + TouchPanel_TSC2046, + // Microchip Touch Screen Controller (AR1021). + TouchPanel_AR1021, + + // Must be after last panel ID + TouchPanelInvalidLast, + // unknown touch panel + TouchPanelUnknown = 0xFF + + }; + + typedef struct { + uint8_t swap; // set to 1 if x and y should be swapped + uint32_t xres; // x resistance + uint32_t yres; // y resistance + TouchPanelId panelId; // identifies touch panel + + } TouchParams_t; + /** Create an interface to an Embedded Artists LCD Board * * @param sda I2C data line pin @@ -111,6 +135,36 @@ */ Result getPowerDownSeq(char* buf, int len); + /** + * Get the touch panel parameters stored in persistent storage + * + * @param params pointer to a configuration object. Parameters are copied to + * this object. + * + * @returns the result of the operation + */ + Result getTouchParameters(TouchParams_t* params); + + /** + * Write display parameters to the EEPROM. Please use this function with + * care since original parameters will be overwritten and cannot be restored. + * + * @param lcdName the name of the display + * @param lcdMfg the display manufacturer + * @param cfg the display configuration parameters + * @param initSeqStr the initialization sequence string + * @param pdSeqStr the power down sequence string + * @param touch touch panel parameters + */ + Result storeParameters( + const char* lcdName, + const char* lcdMfg, + LcdController::Config* cfg, + const char* initSeqStr, + const char* pdSeqStr, + TouchParams_t* touch, + bool controlWp = false); + private: @@ -134,6 +188,7 @@ Result checkVersion(char* v, uint32_t len); Result execDelay(char* del, uint32_t len); Result execSeqCtrl(char* cmd, uint32_t len); + Result execPinSet(char* cmd, uint32_t len); void setLsStates(uint16_t states, uint8_t* ls, uint8_t mode); void setLeds(void); @@ -142,6 +197,7 @@ void pca9532_setBlink0Duty(uint8_t duty); void pca9532_setBlink0Leds(uint16_t ledMask); + void setWriteProtect(bool enable); void set3V3Signal(bool enabled); void set5VSignal(bool enabled); void setDisplayEnableSignal(bool enabled); @@ -157,5 +213,3 @@ }; #endif - -
--- a/GFXFb.cpp Wed Oct 09 07:51:52 2013 +0000 +++ b/GFXFb.cpp Fri Oct 18 12:48:58 2013 +0200 @@ -1,3 +1,8 @@ + +/****************************************************************************** + * Includes + *****************************************************************************/ + #include "mbed.h" #include "GFXFb.h"
--- a/LcdController.cpp Wed Oct 09 07:51:52 2013 +0000 +++ b/LcdController.cpp Fri Oct 18 12:48:58 2013 +0200 @@ -1,7 +1,15 @@ + +/****************************************************************************** + * Includes + *****************************************************************************/ #include "mbed.h" #include "LcdController.h" +/****************************************************************************** + * Defines and typedefs + *****************************************************************************/ + #undef _SBF #define _SBF(p,v) (((uint32_t)(v)) << (p)) @@ -386,7 +394,8 @@ LPC_IOCON->P1_28 |= 7; /* LCD_VD_22 @ P1.28 */ LPC_IOCON->P1_29 |= 7; /* LCD_VD_23 @ P1.29 */ - LPC_IOCON->P2_0 |= 7; /* LCD_PWR @ P2.0 */ + // pwr always controlled by gpio +// LPC_IOCON->P2_0 |= 7; /* LCD_PWR @ P2.0 */ LPC_IOCON->P2_1 |= 7; /* LCD_LE @ P2.1 */ LPC_IOCON->P2_2 |= 7; /* LCD_DCLK @ P2.2 */ LPC_IOCON->P2_3 |= 7; /* LCD_FP @ P2.3 */ @@ -433,5 +442,3 @@ } - -
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MMA7455.cpp Fri Oct 18 12:48:58 2013 +0200 @@ -0,0 +1,298 @@ + +/****************************************************************************** + * Includes + *****************************************************************************/ + +#include "mbed.h" +#include "mbed_debug.h" + +#include "MMA7455.h" + +/****************************************************************************** + * Defines and typedefs + *****************************************************************************/ + +#define MMA7455_I2C_ADDR (0x1D << 1) + +#define MMA7455_ADDR_XOUTL 0x00 +#define MMA7455_ADDR_XOUTH 0x01 +#define MMA7455_ADDR_YOUTL 0x02 +#define MMA7455_ADDR_YOUTH 0x03 +#define MMA7455_ADDR_ZOUTL 0x04 +#define MMA7455_ADDR_ZOUTH 0x05 +#define MMA7455_ADDR_XOUT8 0x06 +#define MMA7455_ADDR_YOUT8 0x07 +#define MMA7455_ADDR_ZOUT8 0x08 +#define MMA7455_ADDR_STATUS 0x09 +#define MMA7455_ADDR_DETSRC 0x0A +#define MMA7455_ADDR_TOUT 0x0B +#define MMA7455_ADDR_I2CAD 0x0D +#define MMA7455_ADDR_USRINF 0x0E +#define MMA7455_ADDR_WHOAMI 0x0F +#define MMA7455_ADDR_XOFFL 0x10 +#define MMA7455_ADDR_XOFFH 0x11 +#define MMA7455_ADDR_YOFFL 0x12 +#define MMA7455_ADDR_YOFFH 0x13 +#define MMA7455_ADDR_ZOFFL 0x14 +#define MMA7455_ADDR_ZOFFH 0x15 +#define MMA7455_ADDR_MCTL 0x16 +#define MMA7455_ADDR_INTRST 0x17 +#define MMA7455_ADDR_CTL1 0x18 +#define MMA7455_ADDR_CTL2 0x19 +#define MMA7455_ADDR_LDTH 0x1A +#define MMA7455_ADDR_PDTH 0x1B +#define MMA7455_ADDR_PW 0x1C +#define MMA7455_ADDR_LT 0x1D +#define MMA7455_ADDR_TW 0x1E + +#define MMA7455_MCTL_MODE(m) ((m) << 0) +#define MMA7455_MCTL_GLVL(g) ((g) << 2) + +#define MMA7455_STATUS_DRDY (1 << 0) +#define MMA7455_STATUS_DOVR (1 << 1) +#define MMA7455_STATUS_PERR (1 << 2) + + +MMA7455::MMA7455(PinName sda, PinName scl) : _i2c(sda, scl) +{ + _mode = ModeStandby; + _range = Range_8g; + + _xOff = 0; + _yOff = 0; + _zOff = 0; +} + +bool MMA7455::setMode(Mode mode) { + bool result = false; + int mCtrl = 0; + + do { + mCtrl = getModeControl(); + if (mCtrl < 0) break; + + mCtrl &= ~(0x03 << 0); + mCtrl |= MMA7455_MCTL_MODE(mode); + + if (setModeControl((uint8_t)mCtrl) < 0) { + break; + } + + _mode = mode; + result = true; + } while(0); + + + + return result; +} + +bool MMA7455::setRange(Range range) { + bool result = false; + int mCtrl = 0; + + do { + mCtrl = getModeControl(); + if (mCtrl < 0) break; + + mCtrl &= ~(0x03 << 2); + mCtrl |= MMA7455_MCTL_GLVL(range); + + if (setModeControl((uint8_t)mCtrl) < 0) { + break; + } + + _range = range; + result = true; + } while(0); + + + + return result; + +} + +bool MMA7455::read(int32_t& x, int32_t& y, int32_t& z) { + bool result = false; + + + // nothing to read in standby mode + if (_mode == ModeStandby) return false; + + // wait for ready flag + int status = 0; + do { + status = getStatus(); + } while (status >= 0 && (status & MMA7455_STATUS_DRDY) == 0); + + + do { + if (status < 0) break; + + + char buf[6]; + buf[0] = MMA7455_ADDR_XOUTL; + if (_i2c.write(MMA7455_I2C_ADDR, buf, 1) != 0) break; + if (_i2c.read(MMA7455_I2C_ADDR, buf, 6) != 0) break; + + // check if second bit is set in high byte -> negative value + // expand negative value to full byte + if (buf[1] & 0x02) buf[1] |= 0xFC; + if (buf[3] & 0x02) buf[3] |= 0xFC; + if (buf[5] & 0x02) buf[5] |= 0xFC; + + x = (int16_t)((buf[1] << 8) | buf[0]) + _xOff; + y = (int16_t)((buf[3] << 8) | buf[2]) + _yOff; + z = (int16_t)((buf[5] << 8) | buf[4]) + _zOff; + + + result = true; + + } while(0); + + + return result; +} + +bool MMA7455::calibrate() { + bool result = false; + bool failed = false; + + int32_t x = 0; + int32_t y = 0; + int32_t z = 0; + + int32_t xr = 0; + int32_t yr = 0; + int32_t zr = 0; + + int xOff = 0; + int yOff = 0; + int zOff = 16; + if (_range == Range_2g) { + zOff = 64; + } + if (_range == Range_4g) { + zOff = 32; + } + + do { + + // get an average of 6 values + for (int i = 0; i < 6; i++) { + if (!read(xr, yr, zr)) { + failed = true; + break; + } + x += xr; + y += yr; + z += zr; + + wait_ms(100); + } + + if (failed) break; + x /= 6; + y /= 6; + z /= 6; + + xOff -= x; + yOff -= y; + zOff -= z; + + /* + * For some reason we have not got correct/reliable calibration + * by using the offset drift registers. Instead we are + * calculating the offsets and store them in member variables. + * + * These member variables are then used in the read() method + */ + + _xOff = xOff; + _yOff = yOff; + _zOff = zOff; + + + result = true; + + } while (0); + + + + return result; +} + +bool MMA7455::setCalibrationOffsets(int32_t xOff, int32_t yOff, int32_t zOff) { + _xOff = xOff; + _yOff = yOff; + _zOff = zOff; + + return true; +} + +bool MMA7455::getCalibrationOffsets(int32_t& xOff, int32_t& yOff, int32_t& zOff) { + xOff = _xOff; + yOff = _yOff; + zOff = _zOff; + + return true; +} + +int MMA7455::getStatus() { + int result = -1; + char data[1]; + + do { + data[0] = MMA7455_ADDR_STATUS; + if (_i2c.write(MMA7455_I2C_ADDR, data, 1) != 0) break; + + if (_i2c.read(MMA7455_I2C_ADDR, data, 1) != 0) break; + + result = data[0]; + + } while (0); + + + + return result; +} + +int MMA7455::getModeControl() { + + int result = -1; + char data[1]; + + do { + data[0] = MMA7455_ADDR_MCTL; + if (_i2c.write(MMA7455_I2C_ADDR, data, 1) != 0) break; + + if (_i2c.read(MMA7455_I2C_ADDR, data, 1) != 0) break; + + result = data[0]; + + } while (0); + + + + return result; +} + +int MMA7455::setModeControl(uint8_t mctl) { + int result = -1; + char data[2]; + + do { + data[0] = MMA7455_ADDR_MCTL; + data[1] = (char)mctl; + if (_i2c.write(MMA7455_I2C_ADDR, data, 2) != 0) break; + + result = 0; + + } while (0); + + + + return result; +} + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MMA7455.h Fri Oct 18 12:48:58 2013 +0200 @@ -0,0 +1,94 @@ + +#ifndef MMA7455_H +#define MMA7455_H + + +/** + * Freescale Accelerometer MMA7455. + */ +class MMA7455 { +public: + + enum Mode { + ModeStandby = 0, + ModeMeasurement = 1, + }; + + /** Acceleration range */ + enum Range { + Range_8g = 0, + Range_2g = 1, + Range_4g = 2 + }; + + /** + * Create an interface to the MMA7455 accelerometer + * + * @param sda I2C data line pin + * @param scl I2C clock line pin + */ + MMA7455(PinName sda, PinName scl); + + bool setMode(Mode mode); + bool setRange(Range range); + + bool read(int32_t& x, int32_t& y, int32_t& z); + + /** + * Calibrate for 0g, that is, calculate offset to achieve + * 0g values when accelerometer is placed on flat surface. + * + * Please make sure the accelerometer is placed on a flat surface before + * calling this function. + * + * @return true if request was successful; otherwise false + */ + bool calibrate(); + + /** + * Get calculated offset values. Offsets will be calculated by the + * calibrate() method. + * + * Use these values and put them in persistent storage to avoid + * having to calibrate the accelerometer after a reset/power cycle. + * + * @param xOff x offset is written to this argument + * @param yOff y offset is written to this argument + * @param zOff z offset is written to this argument + * + * @return true if request was successful; otherwise false + */ + bool getCalibrationOffsets(int32_t& xOff, int32_t& yOff, int32_t& zOff); + + /** + * Set calibration offset values. These values should normally + * at one point in time have been retrieved by calling the + * getCalibrationOffsets method. + * + * + * @param xOff x offset + * @param yOff y offset + * @param zOff z offset + * + * @return true if request was successful; otherwise false + */ + bool setCalibrationOffsets(int32_t xOff, int32_t yOff, int32_t zOff); + + + +private: + + I2C _i2c; + Mode _mode; + Range _range; + int32_t _xOff; + int32_t _yOff; + int32_t _zOff; + + int getStatus(); + int getModeControl(); + int setModeControl(uint8_t mctl); + +}; + +#endif
--- a/TSC2046.cpp Wed Oct 09 07:51:52 2013 +0000 +++ b/TSC2046.cpp Fri Oct 18 12:48:58 2013 +0200 @@ -1,5 +1,6 @@ #include "mbed.h" +#include "mbed_debug.h" #include "TSC2046.h" #ifndef ABS @@ -47,6 +48,7 @@ #define DEBOUNCE_MAX 10 #define DEBOUNCE_TOL 3 + TSC2046::TSC2046(PinName mosi, PinName miso, PinName sck, PinName cs) : _spi(mosi, miso, sck), _cs(cs) { @@ -56,19 +58,39 @@ _spi.frequency(1500000); _calibrated = false; _initialized = false; + + _calibPoint = TSC2046_NUM_CALIB_POINTS+1; + + _insetPx = 15; +} + +bool TSC2046::init(uint16_t width, uint16_t height) { + _width = width; + _height = height; + + _cs = 0; + + _spi.write(REF_ON); + _spi.write((READ_12BIT_SER(ADS_A2A1A0_vaux) | ADS_PD10_ALL_ON)); + _spi.write(PWRDOWN); + + _cs = 1; + + + _initialized = true; + + return true; } -void TSC2046::read(touchCoordinate_t &coord) { +bool TSC2046::read(touchCoordinate_t &coord) { touchCoordinate_t tmpCoord; calibPoint_t displayPoint; calibPoint_t screenSample; - if (!_initialized) { - init(); - _initialized = true; - } + if (!_initialized) return false; + readAndFilter(tmpCoord); @@ -92,54 +114,122 @@ coord.y = tmpCoord.y; } -} - -void TSC2046::calibrate(touchCoordinate_t &ref1, - touchCoordinate_t &ref2, - touchCoordinate_t &ref3, - touchCoordinate_t &scr1, - touchCoordinate_t &scr2, - touchCoordinate_t &scr3) { - - calibPoint_t disp[3]; - calibPoint_t scr[3]; - - disp[0].x = ref1.x; - disp[0].y = ref1.y; - disp[1].x = ref2.x; - disp[1].y = ref2.y; - disp[2].x = ref3.x; - disp[2].y = ref3.y; - - scr[0].x = scr1.x; - scr[0].y = scr1.y; - scr[1].x = scr2.x; - scr[1].y = scr2.y; - scr[2].x = scr3.x; - scr[2].y = scr3.y; - - setCalibrationMatrix(disp, scr, &_calibMatrix); - - _calibrated = true; + return true; } -void TSC2046::uncalibrate() { - _calibrated = false; +bool TSC2046::calibrateStart() { + if (!_initialized) return false; + + _calibPoint = 0; + + return true; +} + +bool TSC2046::getNextCalibratePoint(uint16_t* x, uint16_t* y) { + touchCoordinate_t coord; + + if (!_initialized) return false; + + if (x == NULL || y == NULL) return false; + + if (_calibPoint >= TSC2046_NUM_CALIB_POINTS) return false; + + getCalibratePoint(_calibPoint, &coord.x, &coord.y); + + *x = (uint16_t)coord.x; + *y = (uint16_t)coord.y; + _calibrateValues[_calibPoint][0] = coord; + + return true; +} + +bool TSC2046::waitForCalibratePoint(bool* morePoints, uint32_t timeout) { + int result = 0; + bool ret = false; + int32_t x = 0; + int32_t y = 0; + touchCoordinate_t coord; + + if (!_initialized) return false; + + do { + if (morePoints == NULL || _calibPoint >= TSC2046_NUM_CALIB_POINTS) { + break; + } + + result = waitForTouch(&x, &y, timeout); + if (result != 0) { + debug("wait for touch response failed (%d)\n", result); + break; + } + + coord.x = x; + coord.y = y; + _calibrateValues[_calibPoint][1] = coord; + + _calibPoint++; + *morePoints = (_calibPoint < TSC2046_NUM_CALIB_POINTS); + + if (!(*morePoints)) { + + calibrate( + _calibrateValues[0][0], + _calibrateValues[1][0], + _calibrateValues[2][0], + _calibrateValues[0][1], + _calibrateValues[1][1], + _calibrateValues[2][1]); + } + + + ret = true; + + } while (0); + + + + if (!ret) { + // calibration must restart if an error occurred + _calibPoint = TSC2046_NUM_CALIB_POINTS+1; + } + + + + return ret; + } -void TSC2046::init() { +bool TSC2046::calibrate(touchCoordinate_t* values, int numValues) { + if (values == NULL || numValues < TSC2046_NUM_CALIB_POINTS) return false; + + touchCoordinate_t ref[TSC2046_NUM_CALIB_POINTS]; + touchCoordinate_t scr[TSC2046_NUM_CALIB_POINTS]; - _cs = 0; + for (int i = 0; i < TSC2046_NUM_CALIB_POINTS; i++) { + getCalibratePoint(i, &(ref[i].x), &(ref[i].y)); + scr[i] = values[i]; + } + + calibrate(ref[0], ref[1], ref[2], scr[0], scr[1], scr[2]); - _spi.write(REF_ON); - _spi.write((READ_12BIT_SER(ADS_A2A1A0_vaux) | ADS_PD10_ALL_ON)); - _spi.write(PWRDOWN); + return true; +} + + +bool TSC2046::getCalibrationValues(touchCoordinate_t* values, int numValues) { + if (values == NULL || numValues < TSC2046_NUM_CALIB_POINTS) return false; + if (!_calibrated) return false; - _cs = 1; + for (int i = 0; i < TSC2046_NUM_CALIB_POINTS; i++) { + values[i] = _calibrateValues[i][1]; + } + + return true; } + void TSC2046::readAndFilter(touchCoordinate_t &coord) { int32_t ix, iy, iz1, iz2 = 0; @@ -296,6 +386,90 @@ return ((data[0] << 8) | data[1]); } +void TSC2046::calibrate(touchCoordinate_t &ref1, + touchCoordinate_t &ref2, + touchCoordinate_t &ref3, + touchCoordinate_t &scr1, + touchCoordinate_t &scr2, + touchCoordinate_t &scr3) { + + calibPoint_t disp[3]; + calibPoint_t scr[3]; + + disp[0].x = ref1.x; + disp[0].y = ref1.y; + disp[1].x = ref2.x; + disp[1].y = ref2.y; + disp[2].x = ref3.x; + disp[2].y = ref3.y; + + scr[0].x = scr1.x; + scr[0].y = scr1.y; + scr[1].x = scr2.x; + scr[1].y = scr2.y; + scr[2].x = scr3.x; + scr[2].y = scr3.y; + + setCalibrationMatrix(disp, scr, &_calibMatrix); + + _calibrated = true; + +} + +void TSC2046::getCalibratePoint(int pointNum, int32_t* x, int32_t *y) { + switch(pointNum) { + case 0: + *x = _insetPx; + *y = _height - _insetPx; + break; + case 1: + *x = _width/2; + *y = _insetPx; + break; + case 2: + *x = _width - _insetPx; + *y = _height - _insetPx; + break; + } +} + +int TSC2046::waitForTouch(int32_t* x, int32_t* y, uint32_t timeout) { + Timer t; + touchCoordinate_t coord; + bool waitForRelease = false; + int32_t tx = 0; + int32_t ty = 0; + + + t.start(); + while (timeout == 0 || ((uint32_t)t.read_ms() < timeout)) { + + read(coord); + + if (coord.z == 0 && waitForRelease) { + *x = tx; + *y = ty; + break; + } + + if (coord.z > 0) { + tx = coord.x; + ty = coord.y; + waitForRelease = true; + } + + wait_ms(10); + } + + if (timeout > 0 && (uint32_t)t.read_ms() > timeout) { + return -1; + } + + return 0; + +} + + // ############################################################################ // >>>>>>>> Calibrate code >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -609,6 +783,7 @@ } + // ############################################################################ // <<<<<<<< Calibrate code <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< // ############################################################################
--- a/TSC2046.h Wed Oct 09 07:51:52 2013 +0000 +++ b/TSC2046.h Fri Oct 18 12:48:58 2013 +0200 @@ -2,18 +2,16 @@ #ifndef TSC2046_H #define TSC2046_H +#include "TouchPanel.h" + +#define TSC2046_NUM_CALIB_POINTS (3) /** * Texas Instruments Touch Screen Controller (TSC2046). */ -class TSC2046 { +class TSC2046 : public TouchPanel { public: - typedef struct { - int32_t x; - int32_t y; - int32_t z; - } touchCoordinate_t; /** * Constructor @@ -25,34 +23,41 @@ */ TSC2046(PinName mosi, PinName miso, PinName sck, PinName cs); - /** - * Read coordinates from the touch panel. - * - * Before calibrate() is called this function will return uncalibrated - * values. If there is no touch active the coordinate values will be 0. - * - * @param coord pointer to coordinate object. The read coordinates will be - * written to this object. - */ - void read(touchCoordinate_t &coord); + bool init(uint16_t width, uint16_t height); + + bool read(touchCoordinate_t &coord); + bool calibrateStart(); + bool getNextCalibratePoint(uint16_t* x, uint16_t* y); + bool waitForCalibratePoint(bool* morePoints, uint32_t timeout); /** - * Calibrate touch screen based on three reference points and - * three actual readings. This means that the user must be presented - * with three points (one at a time) and asked to press on these points - * to get an actual reading. + * Calibrate the touch panel with already gathered calibration values. + * The list with calibration points must at one point have been retrieved + * by calling getCalibrationValues; + * + * @param values list with calibration values + * @param numValues the size of the list must match the number of + * calibration points needed for this touch panel (TSC2046_NUM_CALIB_POINTS) + * + * @return true if the request was successful; otherwise false */ - void calibrate(touchCoordinate_t &ref1, - touchCoordinate_t &ref2, - touchCoordinate_t &ref3, - touchCoordinate_t &scr1, - touchCoordinate_t &scr2, - touchCoordinate_t &scr3); + bool calibrate(touchCoordinate_t* values, int numValues); /** - * Reset a previous calibration (in order to do a new calibration) + * Get calibration values for the calibration points used by this touch + * panel. This method may only be called after a successful calibration + * has been performed. + * + * The list with values can be written to persistent storage and used + * to calibrate the display without involving the user. + * + * @param values calibration values will be written to this list + * @param numValues the size of the list must match the number of + * calibration points needed for this touch panel (TSC2046_NUM_CALIB_POINTS) + * + * @return true if the request was successful; otherwise false */ - void uncalibrate(); + bool getCalibrationValues(touchCoordinate_t* values, int numValues); private: @@ -78,11 +83,27 @@ bool _initialized; calibMatrix_t _calibMatrix; - void init(); + uint16_t _width; + uint16_t _height; + int _calibPoint; + int _insetPx; + + touchCoordinate_t _calibrateValues[TSC2046_NUM_CALIB_POINTS][2]; + void readAndFilter(touchCoordinate_t &coord); int32_t getFilteredValue(int cmd); uint16_t spiTransfer(uint8_t cmd); + void calibrate(touchCoordinate_t &ref1, + touchCoordinate_t &ref2, + touchCoordinate_t &ref3, + touchCoordinate_t &scr1, + touchCoordinate_t &scr2, + touchCoordinate_t &scr3); + + void getCalibratePoint(int pointNum, int32_t* x, int32_t *y); + int waitForTouch(int32_t* x, int32_t* y, uint32_t timeout); + int setCalibrationMatrix( calibPoint_t * displayPtr, @@ -92,8 +113,8 @@ calibPoint_t * screenPtr, calibMatrix_t * matrixPtr ); + + }; #endif - -
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TouchPanel.h Fri Oct 18 12:48:58 2013 +0200 @@ -0,0 +1,77 @@ + +#ifndef TOUCHPANEL_H +#define TOUCHPANEL_H + + +/** + * An abstract class that represents touch panels. + */ +class TouchPanel { +public: + + typedef struct { + int32_t x; + int32_t y; + int32_t z; + } touchCoordinate_t; + + + /** + * Initialize the touch controller. This method must be called before + * calibrating or reading data from the controller + * + * @param width the width of the touch panel. This is usually the same as + * the width of the display + * @param height the height of the touch panel. This is usually the same + * as the height of the display. + * + * @return true if the request was successful; otherwise false + */ + virtual bool init(uint16_t width, uint16_t height) = 0; + + /** + * Read coordinates from the touch panel. + * + * @param coord pointer to coordinate object. The read coordinates will be + * written to this object. + */ + virtual bool read(touchCoordinate_t &coord) = 0; + + + /** + * Start to calibrate the display + * + * @return true if the request was successful; otherwise false + */ + virtual bool calibrateStart() = 0; + + /** + * Get the next calibration point. Draw an indicator on the screen + * at the coordinates and ask the user to press/click on the indicator. + * Please note that waitForCalibratePoint() must be called after this + * method. + * + * @param x the x coordinate is written to this argument + * @param y the y coordinate is written to this argument + * + * @return true if the request was successful; otherwise false + */ + virtual bool getNextCalibratePoint(uint16_t* x, uint16_t* y) = 0; + + /** + * Wait for a calibration point to have been pressed and recored. + * This method must be called just after getNextCalibratePoint(). + * + * @param morePoints true is written to this argument if there + * are more calibrations points available; otherwise it will be false + * @param timeout maximum number of milliseconds to wait for + * a calibration point. Set this argument to 0 to wait indefinite. + * + * @return true if the request was successful; otherwise false + */ + virtual bool waitForCalibratePoint(bool* morePoints, uint32_t timeout) = 0; + + +}; + +#endif