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

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?

UserRevisionLine numberNew 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