PinDetect rework, removed the continuous sampling, using just irq, timers and pin state sequence.

Fork of PinDetect by Andy K

Committer:
Geremia
Date:
Fri Jun 12 01:13:07 2015 +0000
Revision:
4:3aca44118b7a
revised comments

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Geremia 4:3aca44118b7a 1 /* PinDetectMod
Geremia 4:3aca44118b7a 2 * Copyright (c) 2015 Giuliano Dianda
Geremia 4:3aca44118b7a 3 * Released under the MIT License: http://mbed.org/license/mit
Geremia 4:3aca44118b7a 4 *
Geremia 4:3aca44118b7a 5 * Rework of: PinDetect by Andy Kirkham
Geremia 4:3aca44118b7a 6 */
Geremia 4:3aca44118b7a 7
Geremia 4:3aca44118b7a 8 /*
Geremia 4:3aca44118b7a 9 Copyright (c) 2010 Andy Kirkham
Geremia 4:3aca44118b7a 10
Geremia 4:3aca44118b7a 11 Permission is hereby granted, free of charge, to any person obtaining a copy
Geremia 4:3aca44118b7a 12 of this software and associated documentation files (the "Software"), to deal
Geremia 4:3aca44118b7a 13 in the Software without restriction, including without limitation the rights
Geremia 4:3aca44118b7a 14 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
Geremia 4:3aca44118b7a 15 copies of the Software, and to permit persons to whom the Software is
Geremia 4:3aca44118b7a 16 furnished to do so, subject to the following conditions:
Geremia 4:3aca44118b7a 17
Geremia 4:3aca44118b7a 18 The above copyright notice and this permission notice shall be included in
Geremia 4:3aca44118b7a 19 all copies or substantial portions of the Software.
Geremia 4:3aca44118b7a 20
Geremia 4:3aca44118b7a 21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
Geremia 4:3aca44118b7a 22 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
Geremia 4:3aca44118b7a 23 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
Geremia 4:3aca44118b7a 24 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
Geremia 4:3aca44118b7a 25 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
Geremia 4:3aca44118b7a 26 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
Geremia 4:3aca44118b7a 27 THE SOFTWARE.
Geremia 4:3aca44118b7a 28 */
Geremia 4:3aca44118b7a 29
Geremia 4:3aca44118b7a 30 #ifndef PIN_DETECT_MOD_H
Geremia 4:3aca44118b7a 31 #define PIN_DETECT_MOD_H
Geremia 4:3aca44118b7a 32
Geremia 4:3aca44118b7a 33 #ifndef MBED_H
Geremia 4:3aca44118b7a 34 #include "mbed.h"
Geremia 4:3aca44118b7a 35 #endif
Geremia 4:3aca44118b7a 36
Geremia 4:3aca44118b7a 37 #ifndef PINDETECT_PINSTATES
Geremia 4:3aca44118b7a 38 #define PINDETECT_PINSTATES
Geremia 4:3aca44118b7a 39
Geremia 4:3aca44118b7a 40 // pin state bitmask
Geremia 4:3aca44118b7a 41 #define S_IDLE 0
Geremia 4:3aca44118b7a 42 #define S_RINGING ((uint32_t)1<<0)
Geremia 4:3aca44118b7a 43 #define S_ASSERTED ((uint32_t)1<<1)
Geremia 4:3aca44118b7a 44 #define S_HELD ((uint32_t)1<<2)
Geremia 4:3aca44118b7a 45
Geremia 4:3aca44118b7a 46 #endif
Geremia 4:3aca44118b7a 47
Geremia 4:3aca44118b7a 48 /** PinDetectMod is a rework of PinDetect, .
Geremia 4:3aca44118b7a 49 *
Geremia 4:3aca44118b7a 50 * Unlike the original PinDetect which samples pin at specified rate, here is all about interrupts and timers,
Geremia 4:3aca44118b7a 51 * because for some application the continuous sampling of a mostly idle pin is an overhead.
Geremia 4:3aca44118b7a 52 * Pin state is evaluated in sequence deasserted->ringing->asserted->(->held_asserted)->ringing->deasserted
Geremia 4:3aca44118b7a 53 * callback function can be attached to these state changes:
Geremia 4:3aca44118b7a 54 * deasserted->asserted (e.g. as soon as button is pressed)
Geremia 4:3aca44118b7a 55 * asserted->deasserted (e.g quick button pulse)
Geremia 4:3aca44118b7a 56 * asserted->held_asserted (e.g. as soon as the button is evaluated to be held)
Geremia 4:3aca44118b7a 57 * held_asserted->deasserted (e.g. long button pulse)
Geremia 4:3aca44118b7a 58 *
Geremia 4:3aca44118b7a 59 * Only callbacks that have been attached will be called by the library.
Geremia 4:3aca44118b7a 60 *
Geremia 4:3aca44118b7a 61 * Example:
Geremia 4:3aca44118b7a 62 * @code
Geremia 4:3aca44118b7a 63 * #include "mbed.h"
Geremia 4:3aca44118b7a 64 * #include "PinDetectMod.h"
Geremia 4:3aca44118b7a 65 *
Geremia 4:3aca44118b7a 66 * DigitalOut led1( LED1 );
Geremia 4:3aca44118b7a 67 * PinDetect pin(p30, PullUp, 0);
Geremia 4:3aca44118b7a 68 *
Geremia 4:3aca44118b7a 69 * void keyPressed( void ) {
Geremia 4:3aca44118b7a 70 * backligh_on();
Geremia 4:3aca44118b7a 71 * }
Geremia 4:3aca44118b7a 72 *
Geremia 4:3aca44118b7a 73 * void keyQuickPulsed( void ) {
Geremia 4:3aca44118b7a 74 * increasevalue();
Geremia 4:3aca44118b7a 75 * }
Geremia 4:3aca44118b7a 76 *
Geremia 4:3aca44118b7a 77 * void keyPressedHeld( void ) {
Geremia 4:3aca44118b7a 78 * beep();
Geremia 4:3aca44118b7a 79 * }
Geremia 4:3aca44118b7a 80 *
Geremia 4:3aca44118b7a 81 * void keyLongPulsed( void ) {
Geremia 4:3aca44118b7a 82 * setup_menu();
Geremia 4:3aca44118b7a 83 * }
Geremia 4:3aca44118b7a 84 *
Geremia 4:3aca44118b7a 85 * int main() {
Geremia 4:3aca44118b7a 86 *
Geremia 4:3aca44118b7a 87 * pin.attach_asserted( &keyPressed );
Geremia 4:3aca44118b7a 88 * pin.attach_deasserted( &keyQuickPulsed );
Geremia 4:3aca44118b7a 89 * pin.attach_asserted_held( &keyPressedHeld );
Geremia 4:3aca44118b7a 90 * pin.attach_deasserted_held( &keyLongPulsed );
Geremia 4:3aca44118b7a 91 *
Geremia 4:3aca44118b7a 92 *
Geremia 4:3aca44118b7a 93 * while( 1 ) {
Geremia 4:3aca44118b7a 94 * led1 = !led1;
Geremia 4:3aca44118b7a 95 * wait( 0.2 );
Geremia 4:3aca44118b7a 96 * }
Geremia 4:3aca44118b7a 97 * }
Geremia 4:3aca44118b7a 98 * @endcode
Geremia 4:3aca44118b7a 99 *
Geremia 4:3aca44118b7a 100 */
Geremia 4:3aca44118b7a 101 class PinDetect {
Geremia 4:3aca44118b7a 102
Geremia 4:3aca44118b7a 103
Geremia 4:3aca44118b7a 104
Geremia 4:3aca44118b7a 105 public:
Geremia 4:3aca44118b7a 106
Geremia 4:3aca44118b7a 107 /** PinDetect constructor
Geremia 4:3aca44118b7a 108 *
Geremia 4:3aca44118b7a 109 * @see http://mbed.org/handbook/DigitalIn
Geremia 4:3aca44118b7a 110 * @param p PinName is a valid pin that supports DigitalIn
Geremia 4:3aca44118b7a 111 * @param m PinMode (PullUp, PullDown, PullNone....)
Geremia 4:3aca44118b7a 112 * @param assertvalue pin state to be considered as asserted (0 or 1)
Geremia 4:3aca44118b7a 113 * @param debounce_us debounce time in microseconds, default 5000
Geremia 4:3aca44118b7a 114 * @param held_us time in microseconds for the state to be considered held_asserted, default 2000000
Geremia 4:3aca44118b7a 115 */
Geremia 4:3aca44118b7a 116 PinDetect(PinName p, PinMode m, int assertvalue, unsigned int debounce_us=5000, unsigned int held_us=2000000): interr(p), _assertvalue(assertvalue)
Geremia 4:3aca44118b7a 117 {
Geremia 4:3aca44118b7a 118 debouncetime=debounce_us;
Geremia 4:3aca44118b7a 119 heldtime=held_us;
Geremia 4:3aca44118b7a 120 bouncein=0;
Geremia 4:3aca44118b7a 121 bounceout=0;
Geremia 4:3aca44118b7a 122 disable();
Geremia 4:3aca44118b7a 123 if (_assertvalue) { // pulse up
Geremia 4:3aca44118b7a 124 interr.rise(this, &PinDetect::startpulse); // first rise then fall
Geremia 4:3aca44118b7a 125 interr.fall(this, &PinDetect::endpulse);
Geremia 4:3aca44118b7a 126
Geremia 4:3aca44118b7a 127 } else { // pulse down
Geremia 4:3aca44118b7a 128 interr.fall(this, &PinDetect::startpulse); // first fall then rise
Geremia 4:3aca44118b7a 129 interr.rise(this, &PinDetect::endpulse);
Geremia 4:3aca44118b7a 130 }
Geremia 4:3aca44118b7a 131 interr.mode(m);
Geremia 4:3aca44118b7a 132 statereset(); // pinstate=S_IDLE;
Geremia 4:3aca44118b7a 133 trig=false;
Geremia 4:3aca44118b7a 134 enable();
Geremia 4:3aca44118b7a 135 }
Geremia 4:3aca44118b7a 136
Geremia 4:3aca44118b7a 137 /** PinDetect destructor
Geremia 4:3aca44118b7a 138 */
Geremia 4:3aca44118b7a 139 ~PinDetect() {
Geremia 4:3aca44118b7a 140 interr.disable_irq();
Geremia 4:3aca44118b7a 141 timeoutbounce.detach();
Geremia 4:3aca44118b7a 142 timeoutheld.detach();
Geremia 4:3aca44118b7a 143 }
Geremia 4:3aca44118b7a 144 /** Disable
Geremia 4:3aca44118b7a 145 */
Geremia 4:3aca44118b7a 146 void disable()
Geremia 4:3aca44118b7a 147 {
Geremia 4:3aca44118b7a 148 interr.disable_irq();
Geremia 4:3aca44118b7a 149 statereset();
Geremia 4:3aca44118b7a 150 }
Geremia 4:3aca44118b7a 151 /** Enable
Geremia 4:3aca44118b7a 152 */
Geremia 4:3aca44118b7a 153 void enable()
Geremia 4:3aca44118b7a 154 {
Geremia 4:3aca44118b7a 155 interr.enable_irq();
Geremia 4:3aca44118b7a 156 statereset();
Geremia 4:3aca44118b7a 157 }
Geremia 4:3aca44118b7a 158
Geremia 4:3aca44118b7a 159 /** Set debounce time
Geremia 4:3aca44118b7a 160 *
Geremia 4:3aca44118b7a 161 * @param dbtime microseconds
Geremia 4:3aca44118b7a 162 */
Geremia 4:3aca44118b7a 163 void setDebounceTime(unsigned int dbtime) { debouncetime = dbtime; }
Geremia 4:3aca44118b7a 164
Geremia 4:3aca44118b7a 165 /** Set time until held assumed.
Geremia 4:3aca44118b7a 166 *
Geremia 4:3aca44118b7a 167 * @param htime microseconds
Geremia 4:3aca44118b7a 168 */
Geremia 4:3aca44118b7a 169 void setHeldTime(unsigned int htime) { heldtime = htime; }
Geremia 4:3aca44118b7a 170
Geremia 4:3aca44118b7a 171
Geremia 4:3aca44118b7a 172 /** Attach a callback function
Geremia 4:3aca44118b7a 173 *
Geremia 4:3aca44118b7a 174 * @code
Geremia 4:3aca44118b7a 175 *
Geremia 4:3aca44118b7a 176 * DigitalOut led1( LED1 );
Geremia 4:3aca44118b7a 177 * PinDetect pin(p30, PullUp, 0);
Geremia 4:3aca44118b7a 178 *
Geremia 4:3aca44118b7a 179 * void myCallback( void ) {
Geremia 4:3aca44118b7a 180 * led1 = 1;
Geremia 4:3aca44118b7a 181 * };
Geremia 4:3aca44118b7a 182 *
Geremia 4:3aca44118b7a 183 * main() {
Geremia 4:3aca44118b7a 184 * pin.attach_asserted( &myCallback );
Geremia 4:3aca44118b7a 185 * }
Geremia 4:3aca44118b7a 186 *
Geremia 4:3aca44118b7a 187 * @endcode
Geremia 4:3aca44118b7a 188 *
Geremia 4:3aca44118b7a 189 * Call this function when a pin is asserted.
Geremia 4:3aca44118b7a 190 * @param function A C function pointer
Geremia 4:3aca44118b7a 191 */
Geremia 4:3aca44118b7a 192 void attach_asserted(void (*function)(void)) {
Geremia 4:3aca44118b7a 193 callbackAsserted.attach( function );
Geremia 4:3aca44118b7a 194 }
Geremia 4:3aca44118b7a 195
Geremia 4:3aca44118b7a 196 /** Attach a callback object/method
Geremia 4:3aca44118b7a 197 *
Geremia 4:3aca44118b7a 198 * @code
Geremia 4:3aca44118b7a 199 *
Geremia 4:3aca44118b7a 200 * class Bar {
Geremia 4:3aca44118b7a 201 * public:
Geremia 4:3aca44118b7a 202 * void myCallback( void ) { led1 = 1; }
Geremia 4:3aca44118b7a 203 * };
Geremia 4:3aca44118b7a 204 *
Geremia 4:3aca44118b7a 205 * DigitalOut led1( LED1 );
Geremia 4:3aca44118b7a 206 * PinDetect pin(p30, PullUp, 0);
Geremia 4:3aca44118b7a 207 * Bar bar;
Geremia 4:3aca44118b7a 208 *
Geremia 4:3aca44118b7a 209 * main() {
Geremia 4:3aca44118b7a 210 * pin.attach_asserted( &bar, &Bar::myCallback );
Geremia 4:3aca44118b7a 211 * }
Geremia 4:3aca44118b7a 212 *
Geremia 4:3aca44118b7a 213 * @endcode
Geremia 4:3aca44118b7a 214 *
Geremia 4:3aca44118b7a 215 * Call this function when a pin is asserted.
Geremia 4:3aca44118b7a 216 * @param object An object that conatins the callback method.
Geremia 4:3aca44118b7a 217 * @param method The method within the object to call.
Geremia 4:3aca44118b7a 218 */
Geremia 4:3aca44118b7a 219 template<typename T>
Geremia 4:3aca44118b7a 220 void attach_asserted(T *object, void (T::*member)(void)) {
Geremia 4:3aca44118b7a 221 callbackAsserted.attach( object, member );
Geremia 4:3aca44118b7a 222 }
Geremia 4:3aca44118b7a 223
Geremia 4:3aca44118b7a 224 /** Attach a callback function
Geremia 4:3aca44118b7a 225 *
Geremia 4:3aca44118b7a 226 * @code
Geremia 4:3aca44118b7a 227 *
Geremia 4:3aca44118b7a 228 * DigitalOut led1( LED1 );
Geremia 4:3aca44118b7a 229 * PinDetect pin(p30, PullUp, 0);
Geremia 4:3aca44118b7a 230 *
Geremia 4:3aca44118b7a 231 * void myCallback( void ) {
Geremia 4:3aca44118b7a 232 * led1 = 0;
Geremia 4:3aca44118b7a 233 * };
Geremia 4:3aca44118b7a 234 *
Geremia 4:3aca44118b7a 235 * main() {
Geremia 4:3aca44118b7a 236 * pin.attach_deasserted( &myCallback );
Geremia 4:3aca44118b7a 237 * }
Geremia 4:3aca44118b7a 238 *
Geremia 4:3aca44118b7a 239 * @endcode
Geremia 4:3aca44118b7a 240 *
Geremia 4:3aca44118b7a 241 * Call this function when a pin is deasserted (short pulse).
Geremia 4:3aca44118b7a 242 * @param function A C function pointer
Geremia 4:3aca44118b7a 243 */
Geremia 4:3aca44118b7a 244 void attach_deasserted(void (*function)(void)) {
Geremia 4:3aca44118b7a 245 callbackDeasserted.attach( function );
Geremia 4:3aca44118b7a 246 }
Geremia 4:3aca44118b7a 247
Geremia 4:3aca44118b7a 248 /** Attach a callback object/method
Geremia 4:3aca44118b7a 249 *
Geremia 4:3aca44118b7a 250 * @code
Geremia 4:3aca44118b7a 251 *
Geremia 4:3aca44118b7a 252 * class Bar {
Geremia 4:3aca44118b7a 253 * public:
Geremia 4:3aca44118b7a 254 * void myCallback( void ) { led1 = 0; }
Geremia 4:3aca44118b7a 255 * };
Geremia 4:3aca44118b7a 256 *
Geremia 4:3aca44118b7a 257 * DigitalOut led1( LED1 );
Geremia 4:3aca44118b7a 258 * PinDetect pin(p30, PullUp, 0);
Geremia 4:3aca44118b7a 259 * Bar bar;
Geremia 4:3aca44118b7a 260 *
Geremia 4:3aca44118b7a 261 * main() {
Geremia 4:3aca44118b7a 262 * pin.attach_deasserted( &bar, &Bar::myCallback );
Geremia 4:3aca44118b7a 263 * }
Geremia 4:3aca44118b7a 264 *
Geremia 4:3aca44118b7a 265 * @endcode
Geremia 4:3aca44118b7a 266 *
Geremia 4:3aca44118b7a 267 * Call this function when a pin is deasserted (short pulse).
Geremia 4:3aca44118b7a 268 * @param object An object that conatins the callback method.
Geremia 4:3aca44118b7a 269 * @param method The method within the object to call.
Geremia 4:3aca44118b7a 270 */
Geremia 4:3aca44118b7a 271 template<typename T>
Geremia 4:3aca44118b7a 272 void attach_deasserted(T *object, void (T::*member)(void)) {
Geremia 4:3aca44118b7a 273 callbackDeasserted.attach( object, member );
Geremia 4:3aca44118b7a 274 }
Geremia 4:3aca44118b7a 275
Geremia 4:3aca44118b7a 276 /** Attach a callback function
Geremia 4:3aca44118b7a 277 *
Geremia 4:3aca44118b7a 278 * @code
Geremia 4:3aca44118b7a 279 *
Geremia 4:3aca44118b7a 280 * DigitalOut led2( LED2 );
Geremia 4:3aca44118b7a 281 * PinDetect pin(p30, PullUp, 0);
Geremia 4:3aca44118b7a 282 *
Geremia 4:3aca44118b7a 283 * void myCallback( void ) {
Geremia 4:3aca44118b7a 284 * led2 = 1;
Geremia 4:3aca44118b7a 285 * };
Geremia 4:3aca44118b7a 286 *
Geremia 4:3aca44118b7a 287 * main() {
Geremia 4:3aca44118b7a 288 * pin.attach_asserted_held( &myCallback );
Geremia 4:3aca44118b7a 289 * }
Geremia 4:3aca44118b7a 290 *
Geremia 4:3aca44118b7a 291 * @endcode
Geremia 4:3aca44118b7a 292 *
Geremia 4:3aca44118b7a 293 * Call this function when a pin is asserted and held.
Geremia 4:3aca44118b7a 294 * @param function A C function pointer
Geremia 4:3aca44118b7a 295 */
Geremia 4:3aca44118b7a 296 void attach_asserted_held(void (*function)(void)) {
Geremia 4:3aca44118b7a 297 callbackAssertedHeld.attach( function );
Geremia 4:3aca44118b7a 298 }
Geremia 4:3aca44118b7a 299
Geremia 4:3aca44118b7a 300 /** Attach a callback object/method
Geremia 4:3aca44118b7a 301 *
Geremia 4:3aca44118b7a 302 * @code
Geremia 4:3aca44118b7a 303 *
Geremia 4:3aca44118b7a 304 * class Bar {
Geremia 4:3aca44118b7a 305 * public:
Geremia 4:3aca44118b7a 306 * void myCallback( void ) { led2 = 0; }
Geremia 4:3aca44118b7a 307 * };
Geremia 4:3aca44118b7a 308 *
Geremia 4:3aca44118b7a 309 * DigitalOut led2( LED2 );
Geremia 4:3aca44118b7a 310 * PinDetect pin(p30, PullUp, 0);
Geremia 4:3aca44118b7a 311 * Bar bar;
Geremia 4:3aca44118b7a 312 *
Geremia 4:3aca44118b7a 313 * main() {
Geremia 4:3aca44118b7a 314 * pin.attach_asserted_held( &bar, &Bar::myCallback );
Geremia 4:3aca44118b7a 315 * }
Geremia 4:3aca44118b7a 316 *
Geremia 4:3aca44118b7a 317 * @endcode
Geremia 4:3aca44118b7a 318 *
Geremia 4:3aca44118b7a 319 * Call this function when a pin is asserted and held.
Geremia 4:3aca44118b7a 320 * @param object An object that conatins the callback method.
Geremia 4:3aca44118b7a 321 * @param method The method within the object to call.
Geremia 4:3aca44118b7a 322 */
Geremia 4:3aca44118b7a 323 template<typename T>
Geremia 4:3aca44118b7a 324 void attach_asserted_held(T *object, void (T::*member)(void)) {
Geremia 4:3aca44118b7a 325 callbackAssertedHeld.attach( object, member );
Geremia 4:3aca44118b7a 326 }
Geremia 4:3aca44118b7a 327
Geremia 4:3aca44118b7a 328 /** Attach a callback function
Geremia 4:3aca44118b7a 329 *
Geremia 4:3aca44118b7a 330 * @code
Geremia 4:3aca44118b7a 331 *
Geremia 4:3aca44118b7a 332 * DigitalOut led3( LED3 );
Geremia 4:3aca44118b7a 333 * PinDetect pin(p30, PullUp, 0);
Geremia 4:3aca44118b7a 334 *
Geremia 4:3aca44118b7a 335 * void myCallback( void ) {
Geremia 4:3aca44118b7a 336 * led3 = 1;
Geremia 4:3aca44118b7a 337 * };
Geremia 4:3aca44118b7a 338 *
Geremia 4:3aca44118b7a 339 * main() {
Geremia 4:3aca44118b7a 340 * pin.attach_deasserted_held( &myCallback );
Geremia 4:3aca44118b7a 341 * }
Geremia 4:3aca44118b7a 342 *
Geremia 4:3aca44118b7a 343 * @endcode
Geremia 4:3aca44118b7a 344 *
Geremia 4:3aca44118b7a 345 * Call this function when a pin is deasserted after being held.
Geremia 4:3aca44118b7a 346 * @param function A C function pointer
Geremia 4:3aca44118b7a 347 */
Geremia 4:3aca44118b7a 348 void attach_deasserted_held(void (*function)(void)) {
Geremia 4:3aca44118b7a 349 callbackDeassertedHeld.attach( function );
Geremia 4:3aca44118b7a 350 }
Geremia 4:3aca44118b7a 351
Geremia 4:3aca44118b7a 352 /** Attach a callback object/method
Geremia 4:3aca44118b7a 353 *
Geremia 4:3aca44118b7a 354 * @code
Geremia 4:3aca44118b7a 355 *
Geremia 4:3aca44118b7a 356 * class Bar {
Geremia 4:3aca44118b7a 357 * public:
Geremia 4:3aca44118b7a 358 * void myCallback( void ) { led3 = 0; }
Geremia 4:3aca44118b7a 359 * };
Geremia 4:3aca44118b7a 360 *
Geremia 4:3aca44118b7a 361 * DigitalOut led3( LED3 );
Geremia 4:3aca44118b7a 362 * PinDetect pin(p30, PullUp, 0);
Geremia 4:3aca44118b7a 363 * Bar bar;
Geremia 4:3aca44118b7a 364 *
Geremia 4:3aca44118b7a 365 * main() {
Geremia 4:3aca44118b7a 366 * pin.attach_deasserted_held( &bar, &Bar::myCallback );
Geremia 4:3aca44118b7a 367 * }
Geremia 4:3aca44118b7a 368 *
Geremia 4:3aca44118b7a 369 * @endcode
Geremia 4:3aca44118b7a 370 *
Geremia 4:3aca44118b7a 371 * Call this function when a pin is deasserted after being held.
Geremia 4:3aca44118b7a 372 * @param object An object that conatins the callback method.
Geremia 4:3aca44118b7a 373 * @param method The method within the object to call.
Geremia 4:3aca44118b7a 374 */
Geremia 4:3aca44118b7a 375 template<typename T>
Geremia 4:3aca44118b7a 376 void attach_deasserted_held(T *object, void (T::*member)(void)) {
Geremia 4:3aca44118b7a 377 callbackDeassertedHeld.attach( object, member );
Geremia 4:3aca44118b7a 378 }
Geremia 4:3aca44118b7a 379
Geremia 4:3aca44118b7a 380 /** operator int()
Geremia 4:3aca44118b7a 381 *
Geremia 4:3aca44118b7a 382 * Read the value of the pin being sampled.
Geremia 4:3aca44118b7a 383 */
Geremia 4:3aca44118b7a 384 operator int() { return interr.read(); }
Geremia 4:3aca44118b7a 385
Geremia 4:3aca44118b7a 386 /** Get the current pin state
Geremia 4:3aca44118b7a 387 *
Geremia 4:3aca44118b7a 388 * @return pinstate bitmask S_HELD|S_ASSERTED|S_RINGING, 0=S_IDLE
Geremia 4:3aca44118b7a 389 */
Geremia 4:3aca44118b7a 390 unsigned int state()
Geremia 4:3aca44118b7a 391 {
Geremia 4:3aca44118b7a 392 return pinstate;
Geremia 4:3aca44118b7a 393 }
Geremia 4:3aca44118b7a 394
Geremia 4:3aca44118b7a 395 /** Reset pinstate to S_IDLE and reset debounce/held timers
Geremia 4:3aca44118b7a 396 */
Geremia 4:3aca44118b7a 397 void statereset()
Geremia 4:3aca44118b7a 398 {
Geremia 4:3aca44118b7a 399 pinstate=S_IDLE;
Geremia 4:3aca44118b7a 400 timeoutheld.detach();
Geremia 4:3aca44118b7a 401 timeoutbounce.detach();
Geremia 4:3aca44118b7a 402 pinstate=S_IDLE;
Geremia 4:3aca44118b7a 403 }
Geremia 4:3aca44118b7a 404 /** Get the total bounces for deasserted->asserted
Geremia 4:3aca44118b7a 405 *
Geremia 4:3aca44118b7a 406 * @return bounces so far
Geremia 4:3aca44118b7a 407 */
Geremia 4:3aca44118b7a 408 unsigned int getbouncein()
Geremia 4:3aca44118b7a 409 {
Geremia 4:3aca44118b7a 410 return bouncein;
Geremia 4:3aca44118b7a 411 }
Geremia 4:3aca44118b7a 412 /** Get the total bounces for asserted->deasserted
Geremia 4:3aca44118b7a 413 *
Geremia 4:3aca44118b7a 414 * @return bounces so far
Geremia 4:3aca44118b7a 415 */
Geremia 4:3aca44118b7a 416 unsigned int getbounceout()
Geremia 4:3aca44118b7a 417 {
Geremia 4:3aca44118b7a 418 return bounceout;
Geremia 4:3aca44118b7a 419 }
Geremia 4:3aca44118b7a 420
Geremia 4:3aca44118b7a 421 protected:
Geremia 4:3aca44118b7a 422
Geremia 4:3aca44118b7a 423 void startpulse()
Geremia 4:3aca44118b7a 424 {
Geremia 4:3aca44118b7a 425 pinstate|=S_RINGING;
Geremia 4:3aca44118b7a 426 if((pinstate&S_ASSERTED)==0) timeoutbounce.attach_us(this, &PinDetect::onasserted, debouncetime);
Geremia 4:3aca44118b7a 427 // else if state is asserted and we are here, it means we are debouncing transition to deasserted, timeout is already attached to ondeasserted()
Geremia 4:3aca44118b7a 428 trig=true; // ISR completed
Geremia 4:3aca44118b7a 429 }
Geremia 4:3aca44118b7a 430
Geremia 4:3aca44118b7a 431 void endpulse()
Geremia 4:3aca44118b7a 432 {
Geremia 4:3aca44118b7a 433 if(!trig) return; // first check if the previous startpulse ISR completed
Geremia 4:3aca44118b7a 434 pinstate|=S_RINGING;
Geremia 4:3aca44118b7a 435
Geremia 4:3aca44118b7a 436 if((pinstate&S_ASSERTED)!=0) // if was asserted or held asserted, debounce transition to deasserted
Geremia 4:3aca44118b7a 437 {
Geremia 4:3aca44118b7a 438 timeoutheld.detach();
Geremia 4:3aca44118b7a 439 timeoutbounce.attach_us(this, &PinDetect::ondeasserted, debouncetime);
Geremia 4:3aca44118b7a 440 }
Geremia 4:3aca44118b7a 441 trig=false;
Geremia 4:3aca44118b7a 442 }
Geremia 4:3aca44118b7a 443
Geremia 4:3aca44118b7a 444 void onasserted()
Geremia 4:3aca44118b7a 445 {
Geremia 4:3aca44118b7a 446 if(interr.read()!=_assertvalue)
Geremia 4:3aca44118b7a 447 {
Geremia 4:3aca44118b7a 448 bouncein++;
Geremia 4:3aca44118b7a 449 return; // was a bounce
Geremia 4:3aca44118b7a 450 }
Geremia 4:3aca44118b7a 451 pinstate|=S_ASSERTED; // set asserted
Geremia 4:3aca44118b7a 452 pinstate&= ~(S_RINGING|S_HELD); // clear ringing and held
Geremia 4:3aca44118b7a 453 timeoutheld.attach_us(this, &PinDetect::onheld, heldtime);
Geremia 4:3aca44118b7a 454 callbackAsserted.call(); // call function for pin state change (deasserted -> asserted)
Geremia 4:3aca44118b7a 455 }
Geremia 4:3aca44118b7a 456
Geremia 4:3aca44118b7a 457 void onheld()
Geremia 4:3aca44118b7a 458 {
Geremia 4:3aca44118b7a 459 if((pinstate&S_RINGING)!=0 || (pinstate&S_ASSERTED)==0 || (interr.read()!=_assertvalue)) return; // to be valid, needs ringing=false asserted=true pinread=assertvalue
Geremia 4:3aca44118b7a 460 pinstate|=S_HELD; // set held
Geremia 4:3aca44118b7a 461 callbackAssertedHeld.call(); // call function for pin state change (asserted -> held asserted)
Geremia 4:3aca44118b7a 462 }
Geremia 4:3aca44118b7a 463
Geremia 4:3aca44118b7a 464 void ondeasserted()
Geremia 4:3aca44118b7a 465 {
Geremia 4:3aca44118b7a 466 if((pinstate&(S_ASSERTED))==0) return; // pinstate was reset externally
Geremia 4:3aca44118b7a 467 if(interr.read()==_assertvalue)
Geremia 4:3aca44118b7a 468 {
Geremia 4:3aca44118b7a 469 bounceout++;
Geremia 4:3aca44118b7a 470 return; // was a bounce
Geremia 4:3aca44118b7a 471 }
Geremia 4:3aca44118b7a 472 if((pinstate&S_HELD)==0) callbackDeasserted.call(); // call function for pin state change (asserted -> deasserted)(quick pulse)
Geremia 4:3aca44118b7a 473 else callbackDeassertedHeld.call(); // call function for pin state change (held asserted -> deasserted)(long pulse)
Geremia 4:3aca44118b7a 474 pinstate=S_IDLE;
Geremia 4:3aca44118b7a 475 }
Geremia 4:3aca44118b7a 476
Geremia 4:3aca44118b7a 477 private:
Geremia 4:3aca44118b7a 478 InterruptIn interr;
Geremia 4:3aca44118b7a 479 Timeout timeoutbounce;
Geremia 4:3aca44118b7a 480 Timeout timeoutheld;
Geremia 4:3aca44118b7a 481 unsigned int debouncetime;
Geremia 4:3aca44118b7a 482 unsigned int heldtime;
Geremia 4:3aca44118b7a 483 int _assertvalue;
Geremia 4:3aca44118b7a 484 FunctionPointer callbackAsserted;
Geremia 4:3aca44118b7a 485 FunctionPointer callbackDeasserted;
Geremia 4:3aca44118b7a 486 FunctionPointer callbackAssertedHeld;
Geremia 4:3aca44118b7a 487 FunctionPointer callbackDeassertedHeld;
Geremia 4:3aca44118b7a 488 volatile unsigned int pinstate;
Geremia 4:3aca44118b7a 489 volatile unsigned int bouncein;
Geremia 4:3aca44118b7a 490 volatile unsigned int bounceout;
Geremia 4:3aca44118b7a 491
Geremia 4:3aca44118b7a 492 bool trig;
Geremia 4:3aca44118b7a 493
Geremia 4:3aca44118b7a 494 };
Geremia 4:3aca44118b7a 495
Geremia 4:3aca44118b7a 496
Geremia 4:3aca44118b7a 497 #endif