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@3:8b5fcf3857ac, 2016-05-17 (annotated)
- Committer:
- duncanFrance
- Date:
- Tue May 17 16:28:08 2016 +0000
- Revision:
- 3:8b5fcf3857ac
- Parent:
- 1:9bd85d0331a8
Can now attach instance methods as callback handlers
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
duncanFrance | 0:3f0160100cc9 | 1 | #ifndef TOUCHSCREEN_H |
duncanFrance | 0:3f0160100cc9 | 2 | #define TOUCHSCREEN_H |
duncanFrance | 0:3f0160100cc9 | 3 | |
duncanFrance | 0:3f0160100cc9 | 4 | /** |
duncanFrance | 0:3f0160100cc9 | 5 | * An interrupt-driven library to interface with touch-screens using the ADS7843 chip. |
duncanFrance | 0:3f0160100cc9 | 6 | * |
duncanFrance | 0:3f0160100cc9 | 7 | * |
duncanFrance | 0:3f0160100cc9 | 8 | **/ |
duncanFrance | 0:3f0160100cc9 | 9 | #include "mbed.h" |
duncanFrance | 0:3f0160100cc9 | 10 | #include "rtos.h" |
duncanFrance | 0:3f0160100cc9 | 11 | |
duncanFrance | 0:3f0160100cc9 | 12 | #define TOUCHSCREEN_SPI_FREQUENCY 500000 |
duncanFrance | 0:3f0160100cc9 | 13 | |
duncanFrance | 0:3f0160100cc9 | 14 | #define TOUCHSCREEN_CMD_GETX 0x90 |
duncanFrance | 0:3f0160100cc9 | 15 | #define TOUCHSCREEN_CMD_GETY 0xD0 |
duncanFrance | 0:3f0160100cc9 | 16 | #define TOUCHSCREEN_PRECISION_8 0x08 |
duncanFrance | 0:3f0160100cc9 | 17 | #define TOUCHSCREEN_PRECISION_12 0x00 |
duncanFrance | 0:3f0160100cc9 | 18 | |
duncanFrance | 0:3f0160100cc9 | 19 | #define TOUCHSCREEN_SIGNAL_START 0x01 |
duncanFrance | 0:3f0160100cc9 | 20 | #define TOUCHSCREEN_SIGNAL_END 0x02 |
duncanFrance | 0:3f0160100cc9 | 21 | #define TOUCHSCREEN_SIGNAL_POLL 0x04 |
duncanFrance | 0:3f0160100cc9 | 22 | |
duncanFrance | 0:3f0160100cc9 | 23 | #define TOUCHSCREEN_POLL_MICROS 50000 |
duncanFrance | 0:3f0160100cc9 | 24 | |
duncanFrance | 0:3f0160100cc9 | 25 | /** |
duncanFrance | 0:3f0160100cc9 | 26 | * Default value for how far the touch position must have moved before a new TouchMove event is raised |
duncanFrance | 0:3f0160100cc9 | 27 | **/ |
duncanFrance | 0:3f0160100cc9 | 28 | #define TOUCHSCREEN_MOVEMENT_THRESHOLD 4 |
duncanFrance | 0:3f0160100cc9 | 29 | #define TOUCHSCREEN_DEBOUNCE_MICROS 50000 |
duncanFrance | 0:3f0160100cc9 | 30 | |
duncanFrance | 0:3f0160100cc9 | 31 | #define TOUCHSCREEN_STATE_IDLE 0 |
duncanFrance | 0:3f0160100cc9 | 32 | #define TOUCHSCREEN_STATE_DEBOUNCE 1 |
duncanFrance | 0:3f0160100cc9 | 33 | #define TOUCHSCREEN_STATE_POLL 2 |
duncanFrance | 0:3f0160100cc9 | 34 | |
duncanFrance | 0:3f0160100cc9 | 35 | #define TOUCHSCREEN_ORIENTATION_LANDSCAPE 0 |
duncanFrance | 0:3f0160100cc9 | 36 | #define TOUCHSCREEN_ORIENTATION_PORTRAIT 1 |
duncanFrance | 0:3f0160100cc9 | 37 | #define TOUCHSCREEN_ORIENTATION_ROTATED 2 |
duncanFrance | 0:3f0160100cc9 | 38 | |
duncanFrance | 0:3f0160100cc9 | 39 | typedef struct TouchPosition { |
duncanFrance | 0:3f0160100cc9 | 40 | // Raw touch position 0 - 4095 |
duncanFrance | 0:3f0160100cc9 | 41 | int x; |
duncanFrance | 0:3f0160100cc9 | 42 | int y; |
duncanFrance | 0:3f0160100cc9 | 43 | |
duncanFrance | 0:3f0160100cc9 | 44 | // Touch position in screen pixels |
duncanFrance | 0:3f0160100cc9 | 45 | int screenX; |
duncanFrance | 0:3f0160100cc9 | 46 | int screenY; |
duncanFrance | 0:3f0160100cc9 | 47 | |
duncanFrance | 0:3f0160100cc9 | 48 | bool valid; |
duncanFrance | 0:3f0160100cc9 | 49 | } TouchPosition; |
duncanFrance | 0:3f0160100cc9 | 50 | |
duncanFrance | 0:3f0160100cc9 | 51 | typedef void (* TouchCallbackHandler)(TouchPosition p); |
duncanFrance | 0:3f0160100cc9 | 52 | |
duncanFrance | 0:3f0160100cc9 | 53 | class TouchScreen |
duncanFrance | 0:3f0160100cc9 | 54 | { |
duncanFrance | 0:3f0160100cc9 | 55 | |
duncanFrance | 0:3f0160100cc9 | 56 | public: |
duncanFrance | 0:3f0160100cc9 | 57 | |
duncanFrance | 0:3f0160100cc9 | 58 | /** |
duncanFrance | 0:3f0160100cc9 | 59 | * Basic setup uses hard-coded defaults so the screen can do something. |
duncanFrance | 0:3f0160100cc9 | 60 | * you'll want to setLCDGeometry() and setCalibration() for your screen |
duncanFrance | 0:3f0160100cc9 | 61 | * Use the TouchScreenCalibrate program to get calibration data for your screen |
duncanFrance | 0:3f0160100cc9 | 62 | **/ |
duncanFrance | 0:3f0160100cc9 | 63 | TouchScreen(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName irq); |
duncanFrance | 0:3f0160100cc9 | 64 | |
duncanFrance | 0:3f0160100cc9 | 65 | /** |
duncanFrance | 0:3f0160100cc9 | 66 | * Register a handler which will be called every time a touch is detected on the screen |
duncanFrance | 0:3f0160100cc9 | 67 | **/ |
duncanFrance | 0:3f0160100cc9 | 68 | void setTouchStartHandler(TouchCallbackHandler handler); |
duncanFrance | 3:8b5fcf3857ac | 69 | |
duncanFrance | 3:8b5fcf3857ac | 70 | template<typename T> |
duncanFrance | 3:8b5fcf3857ac | 71 | void setTouchStartHandler(T* tptr, void (T::*mptr)(TouchPosition)) { |
duncanFrance | 3:8b5fcf3857ac | 72 | _touchStartHandler.attach(tptr, mptr); |
duncanFrance | 3:8b5fcf3857ac | 73 | } |
duncanFrance | 3:8b5fcf3857ac | 74 | |
duncanFrance | 0:3f0160100cc9 | 75 | /** |
duncanFrance | 0:3f0160100cc9 | 76 | * Register a handler which will be called every time a movement greater than a given threshold is detected. |
duncanFrance | 0:3f0160100cc9 | 77 | * You can set the threshold with the setMovementThreshold() method |
duncanFrance | 0:3f0160100cc9 | 78 | **/ |
duncanFrance | 0:3f0160100cc9 | 79 | void setTouchMoveHandler(TouchCallbackHandler handler); |
duncanFrance | 0:3f0160100cc9 | 80 | |
duncanFrance | 3:8b5fcf3857ac | 81 | template<typename T> |
duncanFrance | 3:8b5fcf3857ac | 82 | void setTouchMoveHandler(T* tptr, void (T::*mptr)(TouchPosition)) { |
duncanFrance | 3:8b5fcf3857ac | 83 | _touchMoveHandler.attach(tptr, mptr); |
duncanFrance | 3:8b5fcf3857ac | 84 | } |
duncanFrance | 3:8b5fcf3857ac | 85 | |
duncanFrance | 0:3f0160100cc9 | 86 | /** |
duncanFrance | 0:3f0160100cc9 | 87 | * Register a handler which will be called when a touch stops being detected |
duncanFrance | 0:3f0160100cc9 | 88 | **/ |
duncanFrance | 0:3f0160100cc9 | 89 | void setTouchEndHandler(TouchCallbackHandler handler); |
duncanFrance | 0:3f0160100cc9 | 90 | |
duncanFrance | 3:8b5fcf3857ac | 91 | template<typename T> |
duncanFrance | 3:8b5fcf3857ac | 92 | void setTouchEndHandler(T* tptr, void (T::*mptr)(TouchPosition)) { |
duncanFrance | 3:8b5fcf3857ac | 93 | _touchEndHandler.attach(tptr, mptr); |
duncanFrance | 3:8b5fcf3857ac | 94 | } |
duncanFrance | 3:8b5fcf3857ac | 95 | |
duncanFrance | 0:3f0160100cc9 | 96 | /** |
duncanFrance | 0:3f0160100cc9 | 97 | * Set the dimensions and orientation of the LCD screen |
duncanFrance | 0:3f0160100cc9 | 98 | **/ |
duncanFrance | 0:3f0160100cc9 | 99 | void setLCDGeometry(int width, int height, uint8_t orientation); |
duncanFrance | 0:3f0160100cc9 | 100 | |
duncanFrance | 0:3f0160100cc9 | 101 | /** |
duncanFrance | 0:3f0160100cc9 | 102 | * Set the calibration data used to calculate the screen position in pixels of a touch |
duncanFrance | 0:3f0160100cc9 | 103 | **/ |
duncanFrance | 0:3f0160100cc9 | 104 | void setCalibration(int xmin, int xmax, int ymin, int ymax); |
duncanFrance | 0:3f0160100cc9 | 105 | |
duncanFrance | 0:3f0160100cc9 | 106 | /** |
duncanFrance | 0:3f0160100cc9 | 107 | * Set the amount of movement which must occur before a TouchMove event is raised |
duncanFrance | 0:3f0160100cc9 | 108 | **/ |
duncanFrance | 0:3f0160100cc9 | 109 | void setMovementTheshold(int thresholdInPixels); |
duncanFrance | 0:3f0160100cc9 | 110 | |
duncanFrance | 0:3f0160100cc9 | 111 | private: |
duncanFrance | 0:3f0160100cc9 | 112 | |
duncanFrance | 0:3f0160100cc9 | 113 | /** |
duncanFrance | 0:3f0160100cc9 | 114 | * SPI control |
duncanFrance | 0:3f0160100cc9 | 115 | **/ |
duncanFrance | 0:3f0160100cc9 | 116 | SPI _spi ; |
duncanFrance | 0:3f0160100cc9 | 117 | DigitalOut _cs ; |
duncanFrance | 0:3f0160100cc9 | 118 | |
duncanFrance | 0:3f0160100cc9 | 119 | /** |
duncanFrance | 0:3f0160100cc9 | 120 | * The interrupt pin and its handler |
duncanFrance | 0:3f0160100cc9 | 121 | **/ |
duncanFrance | 0:3f0160100cc9 | 122 | DigitalIn _intPin; |
duncanFrance | 0:3f0160100cc9 | 123 | InterruptIn _int; |
duncanFrance | 0:3f0160100cc9 | 124 | |
duncanFrance | 0:3f0160100cc9 | 125 | uint8_t _precision; |
duncanFrance | 0:3f0160100cc9 | 126 | |
duncanFrance | 0:3f0160100cc9 | 127 | int _lcdWidth; |
duncanFrance | 0:3f0160100cc9 | 128 | int _lcdHeight; |
duncanFrance | 0:3f0160100cc9 | 129 | uint8_t _lcdOrientation; |
duncanFrance | 0:3f0160100cc9 | 130 | |
duncanFrance | 0:3f0160100cc9 | 131 | int _xmin, _xmax, _ymin, _ymax; |
duncanFrance | 0:3f0160100cc9 | 132 | int _movementThresholdSquared; |
duncanFrance | 0:3f0160100cc9 | 133 | |
duncanFrance | 0:3f0160100cc9 | 134 | TouchPosition _currentPosition; |
duncanFrance | 0:3f0160100cc9 | 135 | TouchPosition _lastPosition; |
duncanFrance | 0:3f0160100cc9 | 136 | |
duncanFrance | 0:3f0160100cc9 | 137 | unsigned int _read(uint8_t cmd); |
duncanFrance | 0:3f0160100cc9 | 138 | |
duncanFrance | 0:3f0160100cc9 | 139 | volatile uint8_t _state; |
duncanFrance | 0:3f0160100cc9 | 140 | |
duncanFrance | 0:3f0160100cc9 | 141 | void _fallInterruptHandler(); |
duncanFrance | 0:3f0160100cc9 | 142 | void _riseInterruptHandler(); |
duncanFrance | 0:3f0160100cc9 | 143 | void _tickerInterruptHandler(); |
duncanFrance | 0:3f0160100cc9 | 144 | |
duncanFrance | 0:3f0160100cc9 | 145 | |
duncanFrance | 0:3f0160100cc9 | 146 | void _handleTouchStart(); |
duncanFrance | 0:3f0160100cc9 | 147 | void _handleTouchMoved(); |
duncanFrance | 0:3f0160100cc9 | 148 | void _handleTouchEnd(); |
duncanFrance | 0:3f0160100cc9 | 149 | |
duncanFrance | 0:3f0160100cc9 | 150 | bool _moved(TouchPosition a, TouchPosition b); |
duncanFrance | 0:3f0160100cc9 | 151 | |
duncanFrance | 0:3f0160100cc9 | 152 | TouchPosition _getPosition(); |
duncanFrance | 0:3f0160100cc9 | 153 | |
duncanFrance | 3:8b5fcf3857ac | 154 | FunctionPointerArg1<void,TouchPosition> _touchStartHandler; |
duncanFrance | 3:8b5fcf3857ac | 155 | FunctionPointerArg1<void,TouchPosition> _touchMoveHandler; |
duncanFrance | 3:8b5fcf3857ac | 156 | FunctionPointerArg1<void,TouchPosition> _touchEndHandler; |
duncanFrance | 1:9bd85d0331a8 | 157 | |
duncanFrance | 0:3f0160100cc9 | 158 | Thread* _handlerThread; |
duncanFrance | 0:3f0160100cc9 | 159 | |
duncanFrance | 0:3f0160100cc9 | 160 | // Used to poll the screen while it is being touched to track movement and to debounce edge changes |
duncanFrance | 0:3f0160100cc9 | 161 | Ticker _ticker; |
duncanFrance | 0:3f0160100cc9 | 162 | |
duncanFrance | 0:3f0160100cc9 | 163 | /** |
duncanFrance | 0:3f0160100cc9 | 164 | * Needs to be static because a Thread can't be started on an instance method. |
duncanFrance | 0:3f0160100cc9 | 165 | **/ |
duncanFrance | 0:3f0160100cc9 | 166 | static void _monitor(void const *touchScreen) { |
duncanFrance | 0:3f0160100cc9 | 167 | |
duncanFrance | 0:3f0160100cc9 | 168 | TouchScreen* screen = (TouchScreen*)touchScreen; |
duncanFrance | 0:3f0160100cc9 | 169 | |
duncanFrance | 0:3f0160100cc9 | 170 | while(true) { |
duncanFrance | 0:3f0160100cc9 | 171 | osEvent evt = Thread::signal_wait(0); |
duncanFrance | 0:3f0160100cc9 | 172 | if(evt.status == osEventSignal) { |
duncanFrance | 0:3f0160100cc9 | 173 | if(evt.value.signals & TOUCHSCREEN_SIGNAL_START) { |
duncanFrance | 0:3f0160100cc9 | 174 | screen->_handlerThread->signal_clr(TOUCHSCREEN_SIGNAL_START); |
duncanFrance | 0:3f0160100cc9 | 175 | screen->_handleTouchStart(); |
duncanFrance | 0:3f0160100cc9 | 176 | } |
duncanFrance | 0:3f0160100cc9 | 177 | if(evt.value.signals & TOUCHSCREEN_SIGNAL_END) { |
duncanFrance | 0:3f0160100cc9 | 178 | screen->_handlerThread->signal_clr(TOUCHSCREEN_SIGNAL_END); |
duncanFrance | 0:3f0160100cc9 | 179 | screen->_handleTouchEnd(); |
duncanFrance | 0:3f0160100cc9 | 180 | } |
duncanFrance | 0:3f0160100cc9 | 181 | if(evt.value.signals & TOUCHSCREEN_SIGNAL_POLL) { |
duncanFrance | 0:3f0160100cc9 | 182 | screen->_handlerThread->signal_clr(TOUCHSCREEN_SIGNAL_POLL); |
duncanFrance | 0:3f0160100cc9 | 183 | screen->_handleTouchMoved(); |
duncanFrance | 0:3f0160100cc9 | 184 | } |
duncanFrance | 0:3f0160100cc9 | 185 | } |
duncanFrance | 0:3f0160100cc9 | 186 | } |
duncanFrance | 0:3f0160100cc9 | 187 | } |
duncanFrance | 0:3f0160100cc9 | 188 | |
duncanFrance | 0:3f0160100cc9 | 189 | }; |
duncanFrance | 0:3f0160100cc9 | 190 | |
duncanFrance | 0:3f0160100cc9 | 191 | #endif |