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:
Sat Mar 19 15:39:36 2016 +0000
Revision:
0:3f0160100cc9
Child:
1:9bd85d0331a8
Initial import

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 0:3f0160100cc9 69
duncanFrance 0:3f0160100cc9 70 /**
duncanFrance 0:3f0160100cc9 71 * Register a handler which will be called every time a movement greater than a given threshold is detected.
duncanFrance 0:3f0160100cc9 72 * You can set the threshold with the setMovementThreshold() method
duncanFrance 0:3f0160100cc9 73 **/
duncanFrance 0:3f0160100cc9 74 void setTouchMoveHandler(TouchCallbackHandler handler);
duncanFrance 0:3f0160100cc9 75
duncanFrance 0:3f0160100cc9 76 /**
duncanFrance 0:3f0160100cc9 77 * Register a handler which will be called when a touch stops being detected
duncanFrance 0:3f0160100cc9 78 **/
duncanFrance 0:3f0160100cc9 79 void setTouchEndHandler(TouchCallbackHandler handler);
duncanFrance 0:3f0160100cc9 80
duncanFrance 0:3f0160100cc9 81 /**
duncanFrance 0:3f0160100cc9 82 * Set the dimensions and orientation of the LCD screen
duncanFrance 0:3f0160100cc9 83 **/
duncanFrance 0:3f0160100cc9 84 void setLCDGeometry(int width, int height, uint8_t orientation);
duncanFrance 0:3f0160100cc9 85
duncanFrance 0:3f0160100cc9 86 /**
duncanFrance 0:3f0160100cc9 87 * Set the calibration data used to calculate the screen position in pixels of a touch
duncanFrance 0:3f0160100cc9 88 **/
duncanFrance 0:3f0160100cc9 89 void setCalibration(int xmin, int xmax, int ymin, int ymax);
duncanFrance 0:3f0160100cc9 90
duncanFrance 0:3f0160100cc9 91 /**
duncanFrance 0:3f0160100cc9 92 * Set the amount of movement which must occur before a TouchMove event is raised
duncanFrance 0:3f0160100cc9 93 **/
duncanFrance 0:3f0160100cc9 94 void setMovementTheshold(int thresholdInPixels);
duncanFrance 0:3f0160100cc9 95
duncanFrance 0:3f0160100cc9 96 private:
duncanFrance 0:3f0160100cc9 97
duncanFrance 0:3f0160100cc9 98 /**
duncanFrance 0:3f0160100cc9 99 * SPI control
duncanFrance 0:3f0160100cc9 100 **/
duncanFrance 0:3f0160100cc9 101 SPI _spi ;
duncanFrance 0:3f0160100cc9 102 DigitalOut _cs ;
duncanFrance 0:3f0160100cc9 103
duncanFrance 0:3f0160100cc9 104 /**
duncanFrance 0:3f0160100cc9 105 * The interrupt pin and its handler
duncanFrance 0:3f0160100cc9 106 **/
duncanFrance 0:3f0160100cc9 107 DigitalIn _intPin;
duncanFrance 0:3f0160100cc9 108 InterruptIn _int;
duncanFrance 0:3f0160100cc9 109
duncanFrance 0:3f0160100cc9 110 uint8_t _precision;
duncanFrance 0:3f0160100cc9 111
duncanFrance 0:3f0160100cc9 112 int _lcdWidth;
duncanFrance 0:3f0160100cc9 113 int _lcdHeight;
duncanFrance 0:3f0160100cc9 114 uint8_t _lcdOrientation;
duncanFrance 0:3f0160100cc9 115
duncanFrance 0:3f0160100cc9 116 int _xmin, _xmax, _ymin, _ymax;
duncanFrance 0:3f0160100cc9 117 int _movementThresholdSquared;
duncanFrance 0:3f0160100cc9 118
duncanFrance 0:3f0160100cc9 119 TouchPosition _currentPosition;
duncanFrance 0:3f0160100cc9 120 TouchPosition _lastPosition;
duncanFrance 0:3f0160100cc9 121
duncanFrance 0:3f0160100cc9 122 unsigned int _read(uint8_t cmd);
duncanFrance 0:3f0160100cc9 123
duncanFrance 0:3f0160100cc9 124 volatile uint8_t _state;
duncanFrance 0:3f0160100cc9 125
duncanFrance 0:3f0160100cc9 126 void _fallInterruptHandler();
duncanFrance 0:3f0160100cc9 127 void _riseInterruptHandler();
duncanFrance 0:3f0160100cc9 128 void _tickerInterruptHandler();
duncanFrance 0:3f0160100cc9 129
duncanFrance 0:3f0160100cc9 130
duncanFrance 0:3f0160100cc9 131 void _handleTouchStart();
duncanFrance 0:3f0160100cc9 132 void _handleTouchMoved();
duncanFrance 0:3f0160100cc9 133 void _handleTouchEnd();
duncanFrance 0:3f0160100cc9 134
duncanFrance 0:3f0160100cc9 135 bool _moved(TouchPosition a, TouchPosition b);
duncanFrance 0:3f0160100cc9 136
duncanFrance 0:3f0160100cc9 137 TouchPosition _getPosition();
duncanFrance 0:3f0160100cc9 138
duncanFrance 0:3f0160100cc9 139 TouchCallbackHandler _touchStartHandler;
duncanFrance 0:3f0160100cc9 140 TouchCallbackHandler _touchMoveHandler;
duncanFrance 0:3f0160100cc9 141 TouchCallbackHandler _touchEndHandler;
duncanFrance 0:3f0160100cc9 142
duncanFrance 0:3f0160100cc9 143 Thread* _handlerThread;
duncanFrance 0:3f0160100cc9 144
duncanFrance 0:3f0160100cc9 145 // Used to poll the screen while it is being touched to track movement and to debounce edge changes
duncanFrance 0:3f0160100cc9 146 Ticker _ticker;
duncanFrance 0:3f0160100cc9 147
duncanFrance 0:3f0160100cc9 148 /**
duncanFrance 0:3f0160100cc9 149 * Needs to be static because a Thread can't be started on an instance method.
duncanFrance 0:3f0160100cc9 150 **/
duncanFrance 0:3f0160100cc9 151 static void _monitor(void const *touchScreen) {
duncanFrance 0:3f0160100cc9 152
duncanFrance 0:3f0160100cc9 153 TouchScreen* screen = (TouchScreen*)touchScreen;
duncanFrance 0:3f0160100cc9 154
duncanFrance 0:3f0160100cc9 155 while(true) {
duncanFrance 0:3f0160100cc9 156 osEvent evt = Thread::signal_wait(0);
duncanFrance 0:3f0160100cc9 157 if(evt.status == osEventSignal) {
duncanFrance 0:3f0160100cc9 158 if(evt.value.signals & TOUCHSCREEN_SIGNAL_START) {
duncanFrance 0:3f0160100cc9 159 screen->_handlerThread->signal_clr(TOUCHSCREEN_SIGNAL_START);
duncanFrance 0:3f0160100cc9 160 screen->_handleTouchStart();
duncanFrance 0:3f0160100cc9 161 }
duncanFrance 0:3f0160100cc9 162 if(evt.value.signals & TOUCHSCREEN_SIGNAL_END) {
duncanFrance 0:3f0160100cc9 163 screen->_handlerThread->signal_clr(TOUCHSCREEN_SIGNAL_END);
duncanFrance 0:3f0160100cc9 164 screen->_handleTouchEnd();
duncanFrance 0:3f0160100cc9 165 }
duncanFrance 0:3f0160100cc9 166 if(evt.value.signals & TOUCHSCREEN_SIGNAL_POLL) {
duncanFrance 0:3f0160100cc9 167 screen->_handlerThread->signal_clr(TOUCHSCREEN_SIGNAL_POLL);
duncanFrance 0:3f0160100cc9 168 screen->_handleTouchMoved();
duncanFrance 0:3f0160100cc9 169 }
duncanFrance 0:3f0160100cc9 170 }
duncanFrance 0:3f0160100cc9 171 }
duncanFrance 0:3f0160100cc9 172 }
duncanFrance 0:3f0160100cc9 173
duncanFrance 0:3f0160100cc9 174 };
duncanFrance 0:3f0160100cc9 175
duncanFrance 0:3f0160100cc9 176 #endif