PinDetect

Dependents:   BRW_UF_CONTROLLER System_Project_V6 Asteroids

Committer:
Reiko
Date:
Mon Sep 09 17:30:21 2013 +0000
Revision:
0:d78a22c040e4
Created separate PinDetect library

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Reiko 0:d78a22c040e4 1 /*
Reiko 0:d78a22c040e4 2 Copyright (c) 2010 Andy Kirkham
Reiko 0:d78a22c040e4 3
Reiko 0:d78a22c040e4 4 Permission is hereby granted, free of charge, to any person obtaining a copy
Reiko 0:d78a22c040e4 5 of this software and associated documentation files (the "Software"), to deal
Reiko 0:d78a22c040e4 6 in the Software without restriction, including without limitation the rights
Reiko 0:d78a22c040e4 7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
Reiko 0:d78a22c040e4 8 copies of the Software, and to permit persons to whom the Software is
Reiko 0:d78a22c040e4 9 furnished to do so, subject to the following conditions:
Reiko 0:d78a22c040e4 10
Reiko 0:d78a22c040e4 11 The above copyright notice and this permission notice shall be included in
Reiko 0:d78a22c040e4 12 all copies or substantial portions of the Software.
Reiko 0:d78a22c040e4 13
Reiko 0:d78a22c040e4 14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
Reiko 0:d78a22c040e4 15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
Reiko 0:d78a22c040e4 16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
Reiko 0:d78a22c040e4 17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
Reiko 0:d78a22c040e4 18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
Reiko 0:d78a22c040e4 19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
Reiko 0:d78a22c040e4 20 THE SOFTWARE.
Reiko 0:d78a22c040e4 21 */
Reiko 0:d78a22c040e4 22
Reiko 0:d78a22c040e4 23 #ifndef AJK_PIN_DETECT_H
Reiko 0:d78a22c040e4 24 #define AJK_PIN_DETECT_H
Reiko 0:d78a22c040e4 25
Reiko 0:d78a22c040e4 26 #ifndef MBED_H
Reiko 0:d78a22c040e4 27 #include "mbed.h"
Reiko 0:d78a22c040e4 28 #endif
Reiko 0:d78a22c040e4 29
Reiko 0:d78a22c040e4 30 #ifndef PINDETECT_PIN_ASSTERED
Reiko 0:d78a22c040e4 31 #define PINDETECT_PIN_ASSTERED 1
Reiko 0:d78a22c040e4 32 #endif
Reiko 0:d78a22c040e4 33
Reiko 0:d78a22c040e4 34 #ifndef PINDETECT_SAMPLE_PERIOD
Reiko 0:d78a22c040e4 35 #define PINDETECT_SAMPLE_PERIOD 20000
Reiko 0:d78a22c040e4 36 #endif
Reiko 0:d78a22c040e4 37
Reiko 0:d78a22c040e4 38 #ifndef PINDETECT_ASSERT_COUNT
Reiko 0:d78a22c040e4 39 #define PINDETECT_ASSERT_COUNT 1
Reiko 0:d78a22c040e4 40 #endif
Reiko 0:d78a22c040e4 41
Reiko 0:d78a22c040e4 42 #ifndef PINDETECT_HOLD_COUNT
Reiko 0:d78a22c040e4 43 #define PINDETECT_HOLD_COUNT 50
Reiko 0:d78a22c040e4 44 #endif
Reiko 0:d78a22c040e4 45
Reiko 0:d78a22c040e4 46 namespace AjK {
Reiko 0:d78a22c040e4 47
Reiko 0:d78a22c040e4 48 /** PinDetect adds mechanical switch debouncing to DigitialIn and interrupt callbacks.
Reiko 0:d78a22c040e4 49 *
Reiko 0:d78a22c040e4 50 * This is done by sampling the specified pin at regular intervals and detecting any
Reiko 0:d78a22c040e4 51 * change of state ( 0 -> 1 or 1 -> 0 ). When a state change is detected the attached
Reiko 0:d78a22c040e4 52 * callback handler is called. Additionally, if the pin stays in the same state after
Reiko 0:d78a22c040e4 53 * a state change for a defined period of time, an extra callback is made allowing a
Reiko 0:d78a22c040e4 54 * program to detect when a "key is pressed and held down" rather than a momentary
Reiko 0:d78a22c040e4 55 * key/switch press.
Reiko 0:d78a22c040e4 56 *
Reiko 0:d78a22c040e4 57 * All parameters are customisable which include:-
Reiko 0:d78a22c040e4 58 * <ul>
Reiko 0:d78a22c040e4 59 * <li> The sampling frequency. </li>
Reiko 0:d78a22c040e4 60 * <li> The number of continuous samples until a state change is detected. </li>
Reiko 0:d78a22c040e4 61 * <li> The number of continuous samples until a key is assumed held after a state change. </li>
Reiko 0:d78a22c040e4 62 * <li> The logic level which is assumed to be asserted (0volts or +volts). </li>
Reiko 0:d78a22c040e4 63 * </ul>
Reiko 0:d78a22c040e4 64 *
Reiko 0:d78a22c040e4 65 * Only callbacks that have been attached will be called by the library.
Reiko 0:d78a22c040e4 66 *
Reiko 0:d78a22c040e4 67 * Example:
Reiko 0:d78a22c040e4 68 * @code
Reiko 0:d78a22c040e4 69 * #include "mbed.h"
Reiko 0:d78a22c040e4 70 * #include "PinDetect.h"
Reiko 0:d78a22c040e4 71 *
Reiko 0:d78a22c040e4 72 * PinDetect pin( p30 );
Reiko 0:d78a22c040e4 73 * DigitialOut led1( LED1 );
Reiko 0:d78a22c040e4 74 * DigitialOut led2( LED2 );
Reiko 0:d78a22c040e4 75 * DigitialOut led3( LED3 );
Reiko 0:d78a22c040e4 76 * DigitialOut led4( LED4 );
Reiko 0:d78a22c040e4 77 *
Reiko 0:d78a22c040e4 78 * void keyPressed( void ) {
Reiko 0:d78a22c040e4 79 * led2 = 1;
Reiko 0:d78a22c040e4 80 * led3 = 0;
Reiko 0:d78a22c040e4 81 * led4 = 0;
Reiko 0:d78a22c040e4 82 * }
Reiko 0:d78a22c040e4 83 *
Reiko 0:d78a22c040e4 84 * void keyReleased( void ) {
Reiko 0:d78a22c040e4 85 * led2 = 0;
Reiko 0:d78a22c040e4 86 * led3 = 0;
Reiko 0:d78a22c040e4 87 * led4 = 0;
Reiko 0:d78a22c040e4 88 * }
Reiko 0:d78a22c040e4 89 *
Reiko 0:d78a22c040e4 90 * void keyPressedHeld( void ) {
Reiko 0:d78a22c040e4 91 * led3 = 1;
Reiko 0:d78a22c040e4 92 * }
Reiko 0:d78a22c040e4 93 *
Reiko 0:d78a22c040e4 94 * void keyReleasedHeld( void ) {
Reiko 0:d78a22c040e4 95 * led4 = 1;
Reiko 0:d78a22c040e4 96 * }
Reiko 0:d78a22c040e4 97 *
Reiko 0:d78a22c040e4 98 * int main() {
Reiko 0:d78a22c040e4 99 *
Reiko 0:d78a22c040e4 100 * pin.mode( PullDown );
Reiko 0:d78a22c040e4 101 * pin.attach_asserted( &keyPressed );
Reiko 0:d78a22c040e4 102 * pin.attach_deasserted( &keyReleased );
Reiko 0:d78a22c040e4 103 * pin.attach_asserted_held( &keyPressedHeld );
Reiko 0:d78a22c040e4 104 * pin.attach_deasserted_held( &keyReleasedHeld );
Reiko 0:d78a22c040e4 105 *
Reiko 0:d78a22c040e4 106 * // Sampling does not begin until you set a frequency.
Reiko 0:d78a22c040e4 107 * // The default is 20ms. If you want a different frequency
Reiko 0:d78a22c040e4 108 * // then pass the period in microseconds for example, for 10ms :-
Reiko 0:d78a22c040e4 109 * // pin.setSampleFrequency( 10000 );
Reiko 0:d78a22c040e4 110 * //
Reiko 0:d78a22c040e4 111 * pin.setSampleFrequency(); // Defaults to 20ms.
Reiko 0:d78a22c040e4 112 *
Reiko 0:d78a22c040e4 113 * while( 1 ) {
Reiko 0:d78a22c040e4 114 * led1 = !led1;
Reiko 0:d78a22c040e4 115 * wait( 0.2 );
Reiko 0:d78a22c040e4 116 * }
Reiko 0:d78a22c040e4 117 * }
Reiko 0:d78a22c040e4 118 * @endcode
Reiko 0:d78a22c040e4 119 *
Reiko 0:d78a22c040e4 120 * This example will flash led1 in a similar to a standard starting program.
Reiko 0:d78a22c040e4 121 *
Reiko 0:d78a22c040e4 122 * Applying a "1" (switch on) to pin 30 will switch on led2, removing the "1" to "0"
Reiko 0:d78a22c040e4 123 * (switch off) led2 goes out. Holding the "switch" at one for one second will switch
Reiko 0:d78a22c040e4 124 * on led3. An unasserted P30 (switched off) will, after one second illuminate led4
Reiko 0:d78a22c040e4 125 * when the deasserted calledback is called.
Reiko 0:d78a22c040e4 126 *
Reiko 0:d78a22c040e4 127 * The above is a very basic introduction. For more details:-
Reiko 0:d78a22c040e4 128 * @see example.h
Reiko 0:d78a22c040e4 129 */
Reiko 0:d78a22c040e4 130 class PinDetect {
Reiko 0:d78a22c040e4 131
Reiko 0:d78a22c040e4 132 protected:
Reiko 0:d78a22c040e4 133 DigitalIn *_in;
Reiko 0:d78a22c040e4 134 Ticker *_ticker;
Reiko 0:d78a22c040e4 135 int _prevState;
Reiko 0:d78a22c040e4 136 int _currentStateCounter;
Reiko 0:d78a22c040e4 137 int _sampleTime;
Reiko 0:d78a22c040e4 138 int _assertValue;
Reiko 0:d78a22c040e4 139 int _samplesTillAssertReload;
Reiko 0:d78a22c040e4 140 int _samplesTillAssert;
Reiko 0:d78a22c040e4 141 int _samplesTillHeldReload;
Reiko 0:d78a22c040e4 142 int _samplesTillHeld;
Reiko 0:d78a22c040e4 143 FunctionPointer _callbackAsserted;
Reiko 0:d78a22c040e4 144 FunctionPointer _callbackDeasserted;
Reiko 0:d78a22c040e4 145 FunctionPointer _callbackAssertedHeld;
Reiko 0:d78a22c040e4 146 FunctionPointer _callbackDeassertedHeld;
Reiko 0:d78a22c040e4 147
Reiko 0:d78a22c040e4 148 /** initialise class
Reiko 0:d78a22c040e4 149 *
Reiko 0:d78a22c040e4 150 * @param PinName p is a valid pin that supports DigitalIn
Reiko 0:d78a22c040e4 151 * @param PinMode m The mode the DigitalIn should use.
Reiko 0:d78a22c040e4 152 */
Reiko 0:d78a22c040e4 153 void init(PinName p, PinMode m) {
Reiko 0:d78a22c040e4 154 _sampleTime = PINDETECT_SAMPLE_PERIOD;
Reiko 0:d78a22c040e4 155 _samplesTillAssert = PINDETECT_ASSERT_COUNT;
Reiko 0:d78a22c040e4 156 _samplesTillHeld = 0;
Reiko 0:d78a22c040e4 157 _samplesTillAssertReload = PINDETECT_ASSERT_COUNT;
Reiko 0:d78a22c040e4 158 _samplesTillHeldReload = PINDETECT_HOLD_COUNT;
Reiko 0:d78a22c040e4 159 _assertValue = PINDETECT_PIN_ASSTERED;
Reiko 0:d78a22c040e4 160
Reiko 0:d78a22c040e4 161 _in = new DigitalIn( p );
Reiko 0:d78a22c040e4 162 _in->mode( m );
Reiko 0:d78a22c040e4 163 _prevState = _in->read();
Reiko 0:d78a22c040e4 164 _ticker = new Ticker;
Reiko 0:d78a22c040e4 165 }
Reiko 0:d78a22c040e4 166
Reiko 0:d78a22c040e4 167 public:
Reiko 0:d78a22c040e4 168
Reiko 0:d78a22c040e4 169 friend class Ticker;
Reiko 0:d78a22c040e4 170
Reiko 0:d78a22c040e4 171 PinDetect() { error("You must supply a PinName"); }
Reiko 0:d78a22c040e4 172
Reiko 0:d78a22c040e4 173 /** PinDetect constructor
Reiko 0:d78a22c040e4 174 *
Reiko 0:d78a22c040e4 175 * By default the PinMode is set to PullDown.
Reiko 0:d78a22c040e4 176 *
Reiko 0:d78a22c040e4 177 * @see http://mbed.org/handbook/DigitalIn
Reiko 0:d78a22c040e4 178 * @param p PinName is a valid pin that supports DigitalIn
Reiko 0:d78a22c040e4 179 */
Reiko 0:d78a22c040e4 180 PinDetect(PinName p) {
Reiko 0:d78a22c040e4 181 init( p, PullDown );
Reiko 0:d78a22c040e4 182 }
Reiko 0:d78a22c040e4 183
Reiko 0:d78a22c040e4 184 /** PinDetect constructor
Reiko 0:d78a22c040e4 185 *
Reiko 0:d78a22c040e4 186 * @see http://mbed.org/handbook/DigitalIn
Reiko 0:d78a22c040e4 187 * @param PinName p is a valid pin that supports DigitalIn
Reiko 0:d78a22c040e4 188 * @param PinMode m The mode the DigitalIn should use.
Reiko 0:d78a22c040e4 189 */
Reiko 0:d78a22c040e4 190 PinDetect(PinName p, PinMode m) {
Reiko 0:d78a22c040e4 191 init( p, m );
Reiko 0:d78a22c040e4 192 }
Reiko 0:d78a22c040e4 193
Reiko 0:d78a22c040e4 194 /** PinDetect destructor
Reiko 0:d78a22c040e4 195 */
Reiko 0:d78a22c040e4 196 ~PinDetect() {
Reiko 0:d78a22c040e4 197 if ( _ticker ) delete( _ticker );
Reiko 0:d78a22c040e4 198 if ( _in ) delete( _in );
Reiko 0:d78a22c040e4 199 }
Reiko 0:d78a22c040e4 200
Reiko 0:d78a22c040e4 201 /** Set the sampling time in microseconds.
Reiko 0:d78a22c040e4 202 *
Reiko 0:d78a22c040e4 203 * @param int The time between pin samples in microseconds.
Reiko 0:d78a22c040e4 204 */
Reiko 0:d78a22c040e4 205 void setSampleFrequency(int i = PINDETECT_SAMPLE_PERIOD) {
Reiko 0:d78a22c040e4 206 _sampleTime = i;
Reiko 0:d78a22c040e4 207 _prevState = _in->read();
Reiko 0:d78a22c040e4 208 _ticker->attach_us( this, &PinDetect::isr, _sampleTime );
Reiko 0:d78a22c040e4 209 }
Reiko 0:d78a22c040e4 210
Reiko 0:d78a22c040e4 211 /** Set the value used as assert.
Reiko 0:d78a22c040e4 212 *
Reiko 0:d78a22c040e4 213 * Defaults to 1 (ie if pin == 1 then pin asserted).
Reiko 0:d78a22c040e4 214 *
Reiko 0:d78a22c040e4 215 * @param int New assert value (1 or 0)
Reiko 0:d78a22c040e4 216 */
Reiko 0:d78a22c040e4 217 void setAssertValue (int i = PINDETECT_PIN_ASSTERED) { _assertValue = i & 1; }
Reiko 0:d78a22c040e4 218
Reiko 0:d78a22c040e4 219 /** Set the number of continuous samples until assert assumed.
Reiko 0:d78a22c040e4 220 *
Reiko 0:d78a22c040e4 221 * Defaults to 1 (1 * sample frequency).
Reiko 0:d78a22c040e4 222 *
Reiko 0:d78a22c040e4 223 * @param int The number of continuous samples until assert assumed.
Reiko 0:d78a22c040e4 224 */
Reiko 0:d78a22c040e4 225 void setSamplesTillAssert(int i) { _samplesTillAssertReload = i; }
Reiko 0:d78a22c040e4 226
Reiko 0:d78a22c040e4 227 /** Set the number of continuous samples until held assumed.
Reiko 0:d78a22c040e4 228 *
Reiko 0:d78a22c040e4 229 * Defaults to 50 * sample frequency.
Reiko 0:d78a22c040e4 230 *
Reiko 0:d78a22c040e4 231 * @param int The number of continuous samples until held assumed.
Reiko 0:d78a22c040e4 232 */
Reiko 0:d78a22c040e4 233 void setSamplesTillHeld(int i) { _samplesTillHeldReload = i; }
Reiko 0:d78a22c040e4 234
Reiko 0:d78a22c040e4 235 /** Set the pin mode.
Reiko 0:d78a22c040e4 236 *
Reiko 0:d78a22c040e4 237 * @see http://mbed.org/projects/libraries/api/mbed/trunk/DigitalInOut#DigitalInOut.mode
Reiko 0:d78a22c040e4 238 * @param PinMode m The mode to pass on to the DigitalIn
Reiko 0:d78a22c040e4 239 */
Reiko 0:d78a22c040e4 240 void mode(PinMode m) { _in->mode( m ); }
Reiko 0:d78a22c040e4 241
Reiko 0:d78a22c040e4 242 /** Attach a callback function
Reiko 0:d78a22c040e4 243 *
Reiko 0:d78a22c040e4 244 * @code
Reiko 0:d78a22c040e4 245 *
Reiko 0:d78a22c040e4 246 * DigitalOut led1( LED1 );
Reiko 0:d78a22c040e4 247 * PinDetect pin( p30 );
Reiko 0:d78a22c040e4 248 *
Reiko 0:d78a22c040e4 249 * void myCallback( void ) {
Reiko 0:d78a22c040e4 250 * led1 = 1;
Reiko 0:d78a22c040e4 251 * };
Reiko 0:d78a22c040e4 252 *
Reiko 0:d78a22c040e4 253 * main() {
Reiko 0:d78a22c040e4 254 * pin.attach_asserted( &myCallback );
Reiko 0:d78a22c040e4 255 * }
Reiko 0:d78a22c040e4 256 *
Reiko 0:d78a22c040e4 257 * @endcode
Reiko 0:d78a22c040e4 258 *
Reiko 0:d78a22c040e4 259 * Call this function when a pin is asserted.
Reiko 0:d78a22c040e4 260 * @param function A C function pointer
Reiko 0:d78a22c040e4 261 */
Reiko 0:d78a22c040e4 262 void attach_asserted(void (*function)(void)) {
Reiko 0:d78a22c040e4 263 _callbackAsserted.attach( function );
Reiko 0:d78a22c040e4 264 }
Reiko 0:d78a22c040e4 265
Reiko 0:d78a22c040e4 266 /** Attach a callback object/method
Reiko 0:d78a22c040e4 267 *
Reiko 0:d78a22c040e4 268 * @code
Reiko 0:d78a22c040e4 269 *
Reiko 0:d78a22c040e4 270 * class Bar {
Reiko 0:d78a22c040e4 271 * public:
Reiko 0:d78a22c040e4 272 * void myCallback( void ) { led1 = 1; }
Reiko 0:d78a22c040e4 273 * };
Reiko 0:d78a22c040e4 274 *
Reiko 0:d78a22c040e4 275 * DigitalOut led1( LED1 );
Reiko 0:d78a22c040e4 276 * PinDetect pin( p30 );
Reiko 0:d78a22c040e4 277 * Bar bar;
Reiko 0:d78a22c040e4 278 *
Reiko 0:d78a22c040e4 279 * main() {
Reiko 0:d78a22c040e4 280 * pin.attach_asserted( &bar, &Bar::myCallback );
Reiko 0:d78a22c040e4 281 * }
Reiko 0:d78a22c040e4 282 *
Reiko 0:d78a22c040e4 283 * @endcode
Reiko 0:d78a22c040e4 284 *
Reiko 0:d78a22c040e4 285 * Call this function when a pin is asserted.
Reiko 0:d78a22c040e4 286 * @param object An object that conatins the callback method.
Reiko 0:d78a22c040e4 287 * @param method The method within the object to call.
Reiko 0:d78a22c040e4 288 */
Reiko 0:d78a22c040e4 289 template<typename T>
Reiko 0:d78a22c040e4 290 void attach_asserted(T *object, void (T::*member)(void)) {
Reiko 0:d78a22c040e4 291 _callbackAsserted.attach( object, member );
Reiko 0:d78a22c040e4 292 }
Reiko 0:d78a22c040e4 293
Reiko 0:d78a22c040e4 294 /** Attach a callback function
Reiko 0:d78a22c040e4 295 *
Reiko 0:d78a22c040e4 296 * @code
Reiko 0:d78a22c040e4 297 *
Reiko 0:d78a22c040e4 298 * DigitalOut led1( LED1 );
Reiko 0:d78a22c040e4 299 * PinDetect pin( p30 );
Reiko 0:d78a22c040e4 300 *
Reiko 0:d78a22c040e4 301 * void myCallback( void ) {
Reiko 0:d78a22c040e4 302 * led1 = 0;
Reiko 0:d78a22c040e4 303 * };
Reiko 0:d78a22c040e4 304 *
Reiko 0:d78a22c040e4 305 * main() {
Reiko 0:d78a22c040e4 306 * pin.attach_deasserted( &myCallback );
Reiko 0:d78a22c040e4 307 * }
Reiko 0:d78a22c040e4 308 *
Reiko 0:d78a22c040e4 309 * @endcode
Reiko 0:d78a22c040e4 310 *
Reiko 0:d78a22c040e4 311 * Call this function when a pin is deasserted.
Reiko 0:d78a22c040e4 312 * @param function A C function pointer
Reiko 0:d78a22c040e4 313 */
Reiko 0:d78a22c040e4 314 void attach_deasserted(void (*function)(void)) {
Reiko 0:d78a22c040e4 315 _callbackDeasserted.attach( function );
Reiko 0:d78a22c040e4 316 }
Reiko 0:d78a22c040e4 317
Reiko 0:d78a22c040e4 318 /** Attach a callback object/method
Reiko 0:d78a22c040e4 319 *
Reiko 0:d78a22c040e4 320 * @code
Reiko 0:d78a22c040e4 321 *
Reiko 0:d78a22c040e4 322 * class Bar {
Reiko 0:d78a22c040e4 323 * public:
Reiko 0:d78a22c040e4 324 * void myCallback( void ) { led1 = 0; }
Reiko 0:d78a22c040e4 325 * };
Reiko 0:d78a22c040e4 326 *
Reiko 0:d78a22c040e4 327 * DigitalOut led1( LED1 );
Reiko 0:d78a22c040e4 328 * PinDetect pin( p30 );
Reiko 0:d78a22c040e4 329 * Bar bar;
Reiko 0:d78a22c040e4 330 *
Reiko 0:d78a22c040e4 331 * main() {
Reiko 0:d78a22c040e4 332 * pin.attach_deasserted( &bar, &Bar::myCallback );
Reiko 0:d78a22c040e4 333 * }
Reiko 0:d78a22c040e4 334 *
Reiko 0:d78a22c040e4 335 * @endcode
Reiko 0:d78a22c040e4 336 *
Reiko 0:d78a22c040e4 337 * Call this function when a pin is deasserted.
Reiko 0:d78a22c040e4 338 * @param object An object that conatins the callback method.
Reiko 0:d78a22c040e4 339 * @param method The method within the object to call.
Reiko 0:d78a22c040e4 340 */
Reiko 0:d78a22c040e4 341 template<typename T>
Reiko 0:d78a22c040e4 342 void attach_deasserted(T *object, void (T::*member)(void)) {
Reiko 0:d78a22c040e4 343 _callbackDeasserted.attach( object, member );
Reiko 0:d78a22c040e4 344 }
Reiko 0:d78a22c040e4 345
Reiko 0:d78a22c040e4 346 /** Attach a callback function
Reiko 0:d78a22c040e4 347 *
Reiko 0:d78a22c040e4 348 * @code
Reiko 0:d78a22c040e4 349 *
Reiko 0:d78a22c040e4 350 * DigitalOut led2( LED2 );
Reiko 0:d78a22c040e4 351 * PinDetect pin( p30 );
Reiko 0:d78a22c040e4 352 *
Reiko 0:d78a22c040e4 353 * void myCallback( void ) {
Reiko 0:d78a22c040e4 354 * led2 = 1;
Reiko 0:d78a22c040e4 355 * };
Reiko 0:d78a22c040e4 356 *
Reiko 0:d78a22c040e4 357 * main() {
Reiko 0:d78a22c040e4 358 * pin.attach_asserted_held( &myCallback );
Reiko 0:d78a22c040e4 359 * }
Reiko 0:d78a22c040e4 360 *
Reiko 0:d78a22c040e4 361 * @endcode
Reiko 0:d78a22c040e4 362 *
Reiko 0:d78a22c040e4 363 * Call this function when a pin is asserted and held.
Reiko 0:d78a22c040e4 364 * @param function A C function pointer
Reiko 0:d78a22c040e4 365 */
Reiko 0:d78a22c040e4 366 void attach_asserted_held(void (*function)(void)) {
Reiko 0:d78a22c040e4 367 _callbackAssertedHeld.attach( function );
Reiko 0:d78a22c040e4 368 }
Reiko 0:d78a22c040e4 369
Reiko 0:d78a22c040e4 370 /** Attach a callback object/method
Reiko 0:d78a22c040e4 371 *
Reiko 0:d78a22c040e4 372 * @code
Reiko 0:d78a22c040e4 373 *
Reiko 0:d78a22c040e4 374 * class Bar {
Reiko 0:d78a22c040e4 375 * public:
Reiko 0:d78a22c040e4 376 * void myCallback( void ) { led2 = 0; }
Reiko 0:d78a22c040e4 377 * };
Reiko 0:d78a22c040e4 378 *
Reiko 0:d78a22c040e4 379 * DigitalOut led2( LED2 );
Reiko 0:d78a22c040e4 380 * PinDetect pin( p30 );
Reiko 0:d78a22c040e4 381 * Bar bar;
Reiko 0:d78a22c040e4 382 *
Reiko 0:d78a22c040e4 383 * main() {
Reiko 0:d78a22c040e4 384 * pin.attach_asserted_held( &bar, &Bar::myCallback );
Reiko 0:d78a22c040e4 385 * }
Reiko 0:d78a22c040e4 386 *
Reiko 0:d78a22c040e4 387 * @endcode
Reiko 0:d78a22c040e4 388 *
Reiko 0:d78a22c040e4 389 * Call this function when a pin is asserted and held.
Reiko 0:d78a22c040e4 390 * @param object An object that conatins the callback method.
Reiko 0:d78a22c040e4 391 * @param method The method within the object to call.
Reiko 0:d78a22c040e4 392 */
Reiko 0:d78a22c040e4 393 template<typename T>
Reiko 0:d78a22c040e4 394 void attach_asserted_held(T *object, void (T::*member)(void)) {
Reiko 0:d78a22c040e4 395 _callbackAssertedHeld.attach( object, member );
Reiko 0:d78a22c040e4 396 }
Reiko 0:d78a22c040e4 397
Reiko 0:d78a22c040e4 398 /** Attach a callback function
Reiko 0:d78a22c040e4 399 *
Reiko 0:d78a22c040e4 400 * @code
Reiko 0:d78a22c040e4 401 *
Reiko 0:d78a22c040e4 402 * DigitalOut led3( LED3 );
Reiko 0:d78a22c040e4 403 * PinDetect pin( p30 );
Reiko 0:d78a22c040e4 404 *
Reiko 0:d78a22c040e4 405 * void myCallback( void ) {
Reiko 0:d78a22c040e4 406 * led3 = 1;
Reiko 0:d78a22c040e4 407 * };
Reiko 0:d78a22c040e4 408 *
Reiko 0:d78a22c040e4 409 * main() {
Reiko 0:d78a22c040e4 410 * pin.attach_deasserted_held( &myCallback );
Reiko 0:d78a22c040e4 411 * }
Reiko 0:d78a22c040e4 412 *
Reiko 0:d78a22c040e4 413 * @endcode
Reiko 0:d78a22c040e4 414 *
Reiko 0:d78a22c040e4 415 * Call this function when a pin is deasserted and held.
Reiko 0:d78a22c040e4 416 * @param function A C function pointer
Reiko 0:d78a22c040e4 417 */
Reiko 0:d78a22c040e4 418 void attach_deasserted_held(void (*function)(void)) {
Reiko 0:d78a22c040e4 419 _callbackDeassertedHeld.attach( function );
Reiko 0:d78a22c040e4 420 }
Reiko 0:d78a22c040e4 421
Reiko 0:d78a22c040e4 422 /** Attach a callback object/method
Reiko 0:d78a22c040e4 423 *
Reiko 0:d78a22c040e4 424 * @code
Reiko 0:d78a22c040e4 425 *
Reiko 0:d78a22c040e4 426 * class Bar {
Reiko 0:d78a22c040e4 427 * public:
Reiko 0:d78a22c040e4 428 * void myCallback( void ) { led3 = 0; }
Reiko 0:d78a22c040e4 429 * };
Reiko 0:d78a22c040e4 430 *
Reiko 0:d78a22c040e4 431 * DigitalOut led3( LED3 );
Reiko 0:d78a22c040e4 432 * PinDetect pin( p30 );
Reiko 0:d78a22c040e4 433 * Bar bar;
Reiko 0:d78a22c040e4 434 *
Reiko 0:d78a22c040e4 435 * main() {
Reiko 0:d78a22c040e4 436 * pin.attach_deasserted_held( &bar, &Bar::myCallback );
Reiko 0:d78a22c040e4 437 * }
Reiko 0:d78a22c040e4 438 *
Reiko 0:d78a22c040e4 439 * @endcode
Reiko 0:d78a22c040e4 440 *
Reiko 0:d78a22c040e4 441 * Call this function when a pin is deasserted and held.
Reiko 0:d78a22c040e4 442 * @param object An object that conatins the callback method.
Reiko 0:d78a22c040e4 443 * @param method The method within the object to call.
Reiko 0:d78a22c040e4 444 */
Reiko 0:d78a22c040e4 445 template<typename T>
Reiko 0:d78a22c040e4 446 void attach_deasserted_held(T *object, void (T::*member)(void)) {
Reiko 0:d78a22c040e4 447 _callbackDeassertedHeld.attach( object, member );
Reiko 0:d78a22c040e4 448 }
Reiko 0:d78a22c040e4 449
Reiko 0:d78a22c040e4 450 /** operator int()
Reiko 0:d78a22c040e4 451 *
Reiko 0:d78a22c040e4 452 * Read the value of the pin being sampled.
Reiko 0:d78a22c040e4 453 */
Reiko 0:d78a22c040e4 454 operator int() { return _in->read(); }
Reiko 0:d78a22c040e4 455
Reiko 0:d78a22c040e4 456 protected:
Reiko 0:d78a22c040e4 457 /** The Ticker periodic callback function
Reiko 0:d78a22c040e4 458 */
Reiko 0:d78a22c040e4 459 void isr(void) {
Reiko 0:d78a22c040e4 460 int currentState = _in->read();
Reiko 0:d78a22c040e4 461
Reiko 0:d78a22c040e4 462 if ( currentState != _prevState ) {
Reiko 0:d78a22c040e4 463 if ( _samplesTillAssert == 0 ) {
Reiko 0:d78a22c040e4 464 _prevState = currentState;
Reiko 0:d78a22c040e4 465 _samplesTillHeld = _samplesTillHeldReload;
Reiko 0:d78a22c040e4 466 if ( currentState == _assertValue )
Reiko 0:d78a22c040e4 467 _callbackAsserted.call();
Reiko 0:d78a22c040e4 468 else
Reiko 0:d78a22c040e4 469 _callbackDeasserted.call();
Reiko 0:d78a22c040e4 470 }
Reiko 0:d78a22c040e4 471 else {
Reiko 0:d78a22c040e4 472 _samplesTillAssert--;
Reiko 0:d78a22c040e4 473 }
Reiko 0:d78a22c040e4 474 }
Reiko 0:d78a22c040e4 475 else {
Reiko 0:d78a22c040e4 476 _samplesTillAssert = _samplesTillAssertReload;
Reiko 0:d78a22c040e4 477 }
Reiko 0:d78a22c040e4 478
Reiko 0:d78a22c040e4 479 if ( _samplesTillHeld ) {
Reiko 0:d78a22c040e4 480 if ( _prevState == currentState ) {
Reiko 0:d78a22c040e4 481 _samplesTillHeld--;
Reiko 0:d78a22c040e4 482 if ( _samplesTillHeld == 0 ) {
Reiko 0:d78a22c040e4 483 if ( currentState == _assertValue )
Reiko 0:d78a22c040e4 484 _callbackAssertedHeld.call();
Reiko 0:d78a22c040e4 485 else
Reiko 0:d78a22c040e4 486 _callbackDeassertedHeld.call();
Reiko 0:d78a22c040e4 487 }
Reiko 0:d78a22c040e4 488 }
Reiko 0:d78a22c040e4 489 else {
Reiko 0:d78a22c040e4 490 _samplesTillHeld = 0;
Reiko 0:d78a22c040e4 491 }
Reiko 0:d78a22c040e4 492 }
Reiko 0:d78a22c040e4 493 }
Reiko 0:d78a22c040e4 494
Reiko 0:d78a22c040e4 495 };
Reiko 0:d78a22c040e4 496
Reiko 0:d78a22c040e4 497 }; // namespace AjK ends.
Reiko 0:d78a22c040e4 498
Reiko 0:d78a22c040e4 499 using namespace AjK;
Reiko 0:d78a22c040e4 500
Reiko 0:d78a22c040e4 501 #endif