mbed Advent Calendar 2014 day 8 (http://www.adventar.org/calendars/523)

Dependencies:   USBDevice mbed

Committer:
hsgw
Date:
Mon Dec 08 12:31:18 2014 +0000
Revision:
0:23d012049941
1st commit

Who changed what in which revision?

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