A board support package for the LPC4088 Display Module.
Dependencies: DM_HttpServer DM_USBHost
Dependents: lpc4088_displaymodule_emwin lpc4088_displaymodule_demo_sphere sampleGUI sampleEmptyGUI ... more
Fork of DMSupport by
Display/BiosTouch.cpp
- Committer:
- embeddedartists
- Date:
- 2015-01-16
- Revision:
- 23:6afd6a716e80
- Parent:
- 22:1a58a518435c
- Child:
- 24:9a677afc86f1
File content as of revision 23:6afd6a716e80:
/* * Copyright 2014 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. */ #include "mbed.h" #include "BiosTouch.h" #include "BiosLoader.h" #include "DMBoard.h" #include "bios.h" #include "meas.h" /****************************************************************************** * Defines and typedefs *****************************************************************************/ #define SIG_NEW_DATA 0x1 class TouchHandler { public: TouchHandler(bios_header_t* bios, void* biosData, int num) : _latest(NULL), _touchIRQ(P2_25), _bios(bios), _biosData(biosData), _haveData(false), _points(num), _thread(NULL), _listener(NULL) {} void handleTouchInterrupt(); void changeTouchInterrupt(bool enable, bool rising); TouchPanel::TouchError read(touch_coordinate_t* coord, int num); void run(); void setThread(Thread* t) { _thread = t; } FunctionPointer* setListener(FunctionPointer* listener); private: Mutex _mutex; touch_coordinate_t* _latest; InterruptIn _touchIRQ; bios_header_t* _bios; void* _biosData; bool _haveData; //TODO: improve int _points; Thread* _thread; FunctionPointer* _listener; }; /****************************************************************************** * Local variables *****************************************************************************/ /****************************************************************************** * Private Functions *****************************************************************************/ BiosTouch::BiosTouch() : _initialized(false), _haveInfo(false), _poweredOn(false), //_touchIRQ(P2_25), _bios(NULL), _biosData(NULL), _handlerThread(NULL), _handler(NULL), _supportsTouch(false) { } BiosTouch::~BiosTouch() { // _bios and _biosData are deallocated by BiosLoader if (_handlerThread != NULL) { delete _handlerThread; _handlerThread = NULL; } if (_handler != NULL) { delete _handler; _handler = NULL; } } // Function called from the BIOS static void touchIrqEnabler(uint32_t arg, bool enable, bool rising) { ((TouchHandler*)arg)->changeTouchInterrupt(enable, rising); #if defined(DM_BOARD_ENABLE_MEASSURING_PINS) if (enable) { SET_MEAS_PIN_1(); } else { CLR_MEAS_PIN_1(); } #endif } static void touchTask(void const* args) { ((TouchHandler*)args)->run(); } void TouchHandler::run() { RtosLog* log = DMBoard::instance().logger(); BiosError_t err; _latest = (touch_coordinate_t*)malloc(_points*sizeof(touch_coordinate_t)); if (_latest == NULL) { log->printf("Failed to allocate memory for touch events\n"); mbed_die(); } memset(_latest, 0, _points*sizeof(touch_coordinate_t)); while(true) { Thread::signal_wait(SIG_NEW_DATA); // if (_haveData) { // _haveData = false; SET_MEAS_PIN_3(); _bios->touchIrqHandler(_biosData); CLR_MEAS_PIN_3(); //read _mutex.lock(); err = _bios->touchRead(_biosData, _latest, _points); FunctionPointer* fp = _listener; _mutex.unlock(); if (err == BiosError_Ok) { //notify registered callbacks if (fp != NULL) { SET_MEAS_PIN_4(); fp->call(); SET_MEAS_PIN_4(); } } else { log->printf("Failed to read touch event, err = %d\n", err); } // } } //if (_latest != NULL) { // free(_latest); // _latest = NULL; //} } TouchPanel::TouchError TouchHandler::read(touch_coordinate_t* coord, int num) { if (num > _points || num < 1) { return TouchPanel::TouchError_InvalidParam; } _mutex.lock(); memcpy(coord, _latest, num*sizeof(touch_coordinate_t)); _mutex.unlock(); return TouchPanel::TouchError_Ok; } void TouchHandler::handleTouchInterrupt() { SET_MEAS_PIN_2(); //_haveData = true; if (_thread != NULL) { _thread->signal_set(SIG_NEW_DATA); } CLR_MEAS_PIN_2(); } void TouchHandler::changeTouchInterrupt(bool enable, bool rising) { if (enable) { if (rising) { _touchIRQ.rise(this, &TouchHandler::handleTouchInterrupt); } else { _touchIRQ.fall(this, &TouchHandler::handleTouchInterrupt); } } else { if (rising) { _touchIRQ.rise(NULL); } else { _touchIRQ.fall(NULL); } } } FunctionPointer* TouchHandler::setListener(FunctionPointer* listener) { _mutex.lock(); FunctionPointer* old = _listener; _listener = listener; _mutex.unlock(); return old; } /****************************************************************************** * Public Functions *****************************************************************************/ BiosTouch::TouchError BiosTouch::init() { TouchError result = TouchError_Ok; if (!_initialized) { do { if (BiosLoader::instance().params(&_bios, &_biosData) != DMBoard::Ok) { result = TouchError_ConfigError; break; } result = (TouchError)_bios->touchInformation(_biosData, &_supportsTouch, &_supportsTouchCalibration, &_touchIsResistive, &_touchNumFingers); if (result != TouchError_Ok) { break; } _haveInfo = true; // is it supported at all? if (!_supportsTouch) { result = TouchError_TouchNotSupported; break; } _handler = new TouchHandler(_bios, _biosData, _touchNumFingers); result = (TouchError)_bios->touchInit(_biosData, touchIrqEnabler, (uint32_t)_handler); if (result != TouchError_Ok) { break; } result = (TouchError)_bios->touchPowerUp(_biosData); if (result != TouchError_Ok) { break; } _handlerThread = new Thread(touchTask, _handler); _handler->setThread(_handlerThread); _initialized = true; } while(0); if (!_initialized) { if (_handler != NULL) { delete _handler; _handler = NULL; } } } return result; } BiosTouch::TouchError BiosTouch::read(touch_coordinate_t &coord) { TouchError err = TouchError_Ok; if (!_initialized) { err = TouchError_NoInit; } else { err = _handler->read(&coord, 1); } return err; } BiosTouch::TouchError BiosTouch::read(touch_coordinate_t* coord, int num) { TouchError err = TouchError_Ok; if (!_initialized) { err = TouchError_NoInit; } else { err = _handler->read(coord, num); } return err; } BiosTouch::TouchError BiosTouch::info(bool* resistive, int* maxPoints, bool* calibrated) { TouchError err = TouchError_Ok; if (!_haveInfo) { err = TouchError_NoInit; } else { *resistive = _touchIsResistive; *maxPoints = _touchNumFingers; *calibrated = _supportsTouchCalibration; } return err; } bool BiosTouch::isTouchSupported() { #if defined(DM_BOARD_USE_TOUCH) if (_haveInfo) { return _supportsTouch; } #endif return false; } BiosTouch::TouchError BiosTouch::calibrateStart() { TouchError err = TouchError_Ok; if (!_initialized) { err = TouchError_NoInit; } else { err = (TouchError)_bios->touchCalibrateStart(_biosData); } return err; } BiosTouch::TouchError BiosTouch::getNextCalibratePoint(uint16_t* x, uint16_t* y, bool* last) { TouchError err = TouchError_Ok; if (!_initialized) { err = TouchError_NoInit; } else { err = (TouchError)_bios->touchGetNextCalibPoint(_biosData, x, y, last); } return err; } BiosTouch::TouchError BiosTouch::waitForCalibratePoint(bool* morePoints, uint32_t timeout) { TouchError err = TouchError_Ok; if (!_initialized) { err = TouchError_NoInit; } else { err = (TouchError)_bios->touchWaitForCalibratePoint(_biosData, morePoints, timeout); } return err; } FunctionPointer* BiosTouch::setListener(FunctionPointer* listener) { if (_initialized) { return _handler->setListener(listener); } return NULL; }