A library for ADS7843 touch-screens which is interrupt driven, allowing you to register callback handlers for touchStart, touchMove and touchEnd events.
Dependents: TouchScreenCalibrate TouchScreenGUIDemo
TouchScreen.h
- Committer:
- duncanFrance
- Date:
- 2016-05-17
- Revision:
- 3:8b5fcf3857ac
- Parent:
- 1:9bd85d0331a8
File content as of revision 3:8b5fcf3857ac:
#ifndef TOUCHSCREEN_H #define TOUCHSCREEN_H /** * An interrupt-driven library to interface with touch-screens using the ADS7843 chip. * * **/ #include "mbed.h" #include "rtos.h" #define TOUCHSCREEN_SPI_FREQUENCY 500000 #define TOUCHSCREEN_CMD_GETX 0x90 #define TOUCHSCREEN_CMD_GETY 0xD0 #define TOUCHSCREEN_PRECISION_8 0x08 #define TOUCHSCREEN_PRECISION_12 0x00 #define TOUCHSCREEN_SIGNAL_START 0x01 #define TOUCHSCREEN_SIGNAL_END 0x02 #define TOUCHSCREEN_SIGNAL_POLL 0x04 #define TOUCHSCREEN_POLL_MICROS 50000 /** * Default value for how far the touch position must have moved before a new TouchMove event is raised **/ #define TOUCHSCREEN_MOVEMENT_THRESHOLD 4 #define TOUCHSCREEN_DEBOUNCE_MICROS 50000 #define TOUCHSCREEN_STATE_IDLE 0 #define TOUCHSCREEN_STATE_DEBOUNCE 1 #define TOUCHSCREEN_STATE_POLL 2 #define TOUCHSCREEN_ORIENTATION_LANDSCAPE 0 #define TOUCHSCREEN_ORIENTATION_PORTRAIT 1 #define TOUCHSCREEN_ORIENTATION_ROTATED 2 typedef struct TouchPosition { // Raw touch position 0 - 4095 int x; int y; // Touch position in screen pixels int screenX; int screenY; bool valid; } TouchPosition; typedef void (* TouchCallbackHandler)(TouchPosition p); class TouchScreen { public: /** * Basic setup uses hard-coded defaults so the screen can do something. * you'll want to setLCDGeometry() and setCalibration() for your screen * Use the TouchScreenCalibrate program to get calibration data for your screen **/ TouchScreen(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName irq); /** * Register a handler which will be called every time a touch is detected on the screen **/ void setTouchStartHandler(TouchCallbackHandler handler); template<typename T> void setTouchStartHandler(T* tptr, void (T::*mptr)(TouchPosition)) { _touchStartHandler.attach(tptr, mptr); } /** * Register a handler which will be called every time a movement greater than a given threshold is detected. * You can set the threshold with the setMovementThreshold() method **/ void setTouchMoveHandler(TouchCallbackHandler handler); template<typename T> void setTouchMoveHandler(T* tptr, void (T::*mptr)(TouchPosition)) { _touchMoveHandler.attach(tptr, mptr); } /** * Register a handler which will be called when a touch stops being detected **/ void setTouchEndHandler(TouchCallbackHandler handler); template<typename T> void setTouchEndHandler(T* tptr, void (T::*mptr)(TouchPosition)) { _touchEndHandler.attach(tptr, mptr); } /** * Set the dimensions and orientation of the LCD screen **/ void setLCDGeometry(int width, int height, uint8_t orientation); /** * Set the calibration data used to calculate the screen position in pixels of a touch **/ void setCalibration(int xmin, int xmax, int ymin, int ymax); /** * Set the amount of movement which must occur before a TouchMove event is raised **/ void setMovementTheshold(int thresholdInPixels); private: /** * SPI control **/ SPI _spi ; DigitalOut _cs ; /** * The interrupt pin and its handler **/ DigitalIn _intPin; InterruptIn _int; uint8_t _precision; int _lcdWidth; int _lcdHeight; uint8_t _lcdOrientation; int _xmin, _xmax, _ymin, _ymax; int _movementThresholdSquared; TouchPosition _currentPosition; TouchPosition _lastPosition; unsigned int _read(uint8_t cmd); volatile uint8_t _state; void _fallInterruptHandler(); void _riseInterruptHandler(); void _tickerInterruptHandler(); void _handleTouchStart(); void _handleTouchMoved(); void _handleTouchEnd(); bool _moved(TouchPosition a, TouchPosition b); TouchPosition _getPosition(); FunctionPointerArg1<void,TouchPosition> _touchStartHandler; FunctionPointerArg1<void,TouchPosition> _touchMoveHandler; FunctionPointerArg1<void,TouchPosition> _touchEndHandler; Thread* _handlerThread; // Used to poll the screen while it is being touched to track movement and to debounce edge changes Ticker _ticker; /** * Needs to be static because a Thread can't be started on an instance method. **/ static void _monitor(void const *touchScreen) { TouchScreen* screen = (TouchScreen*)touchScreen; while(true) { osEvent evt = Thread::signal_wait(0); if(evt.status == osEventSignal) { if(evt.value.signals & TOUCHSCREEN_SIGNAL_START) { screen->_handlerThread->signal_clr(TOUCHSCREEN_SIGNAL_START); screen->_handleTouchStart(); } if(evt.value.signals & TOUCHSCREEN_SIGNAL_END) { screen->_handlerThread->signal_clr(TOUCHSCREEN_SIGNAL_END); screen->_handleTouchEnd(); } if(evt.value.signals & TOUCHSCREEN_SIGNAL_POLL) { screen->_handlerThread->signal_clr(TOUCHSCREEN_SIGNAL_POLL); screen->_handleTouchMoved(); } } } } }; #endif