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
Diff: TouchScreen.h
- Revision:
- 0:3f0160100cc9
- Child:
- 1:9bd85d0331a8
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TouchScreen.h Sat Mar 19 15:39:36 2016 +0000 @@ -0,0 +1,176 @@ +#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); + + /** + * 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); + + /** + * Register a handler which will be called when a touch stops being detected + **/ + void setTouchEndHandler(TouchCallbackHandler handler); + + /** + * 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(); + + TouchCallbackHandler _touchStartHandler; + TouchCallbackHandler _touchMoveHandler; + TouchCallbackHandler _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 \ No newline at end of file