Mbed OS 5
Fork of PinDetect by
Rewritten to Mbed OS 5 and their callback mechanism
Diff: PinDetect.h
- Revision:
- 4:bacc386fe2ad
- Parent:
- 3:8e3abbd21291
- Child:
- 5:2b0afd293d1d
--- a/PinDetect.h Thu Jul 28 15:28:17 2016 +0000 +++ b/PinDetect.h Wed Nov 16 23:20:29 2016 +0000 @@ -45,91 +45,115 @@ namespace AjK { -/** PinDetect adds mechanical switch debouncing to DigitialIn and interrupt callbacks. - * - * This is done by sampling the specified pin at regular intervals and detecting any - * change of state ( 0 -> 1 or 1 -> 0 ). When a state change is detected the attached - * callback handler is called. Additionally, if the pin stays in the same state after - * a state change for a defined period of time, an extra callback is made allowing a - * program to detect when a "key is pressed and held down" rather than a momentary - * key/switch press. - * - * All parameters are customisable which include:- - * <ul> - * <li> The sampling frequency. </li> - * <li> The number of continuous samples until a state change is detected. </li> - * <li> The number of continuous samples until a key is assumed held after a state change. </li> - * <li> The logic level which is assumed to be asserted (0volts or +volts). </li> - * </ul> - * - * Only callbacks that have been attached will be called by the library. - * - * Example: - * @code - * #include "mbed.h" - * #include "PinDetect.h" - * - * PinDetect pin( p30 ); - * DigitialOut led1( LED1 ); - * DigitialOut led2( LED2 ); - * DigitialOut led3( LED3 ); - * DigitialOut led4( LED4 ); - * - * void keyPressed( void ) { - * led2 = 1; - * led3 = 0; - * led4 = 0; - * } - * - * void keyReleased( void ) { - * led2 = 0; - * led3 = 0; - * led4 = 0; - * } - * - * void keyPressedHeld( void ) { - * led3 = 1; - * } - * - * void keyReleasedHeld( void ) { - * led4 = 1; - * } - * - * int main() { - * - * pin.mode( PullDown ); - * pin.attach_asserted( &keyPressed ); - * pin.attach_deasserted( &keyReleased ); - * pin.attach_asserted_held( &keyPressedHeld ); - * pin.attach_deasserted_held( &keyReleasedHeld ); - * - * // Sampling does not begin until you set a frequency. - * // The default is 20ms. If you want a different frequency - * // then pass the period in microseconds for example, for 10ms :- - * // pin.setSampleFrequency( 10000 ); - * // - * pin.setSampleFrequency(); // Defaults to 20ms. - * - * while( 1 ) { - * led1 = !led1; - * wait( 0.2 ); - * } - * } - * @endcode - * - * This example will flash led1 in a similar to a standard starting program. - * - * Applying a "1" (switch on) to pin 30 will switch on led2, removing the "1" to "0" - * (switch off) led2 goes out. Holding the "switch" at one for one second will switch - * on led3. An unasserted P30 (switched off) will, after one second illuminate led4 - * when the deasserted calledback is called. - * - * The above is a very basic introduction. For more details:- - * @see example.h - */ class PinDetect { -protected: +public: + friend class Ticker; + + + /** PinDetect constructor + * + * By default the PinMode is set to PullDown. + * + * @see http://mbed.org/handbook/DigitalIn + * @param p PinName is a valid pin that supports DigitalIn + */ + PinDetect(PinName p); + + /** PinDetect constructor + * + * @see http://mbed.org/handbook/DigitalIn + * @param PinName p is a valid pin that supports DigitalIn + * @param PinMode m The mode the DigitalIn should use. + */ + PinDetect(PinName p, PinMode m); + + /** PinDetect destructor + */ + virtual ~PinDetect(void); + + /** Set the sampling time in microseconds. + * + * @param int The time between pin samples in microseconds. + */ + void setSampleFrequency(int i = PINDETECT_SAMPLE_PERIOD); + + /** Set the value used as assert. + * + * Defaults to 1 (ie if pin == 1 then pin asserted). + * + * @param int New assert value (1 or 0) + */ + void setAssertValue (int i = PINDETECT_PIN_ASSTERED); + + /** Set the number of continuous samples until assert assumed. + * + * Defaults to 1 (1 * sample frequency). + * + * @param int The number of continuous samples until assert assumed. + */ + void setSamplesTillAssert(int i); + + /** Set the number of continuous samples until held assumed. + * + * Defaults to 50 * sample frequency. + * + * @param int The number of continuous samples until held assumed. + */ + void setSamplesTillHeld(int i); + + /** Set the pin mode. + * + * @see http://mbed.org/projects/libraries/api/mbed/trunk/DigitalInOut#DigitalInOut.mode + * @param PinMode m The mode to pass on to the DigitalIn + */ + void mode(PinMode m); + + void attach_asserted(Callback<void()> function); + + template<typename T, typename M> + void attach_asserted(T *obj, M method){ + core_util_critical_section_enter(); + attach_asserted(callback(obj, method)); + core_util_critical_section_exit(); + } + + void attach_deasserted(Callback<void()> function); + + template<typename T, typename M> + void attach_deasserted(T *obj, M method){ + core_util_critical_section_enter(); + attach_deasserted(callback(obj, method)); + core_util_critical_section_exit(); + } + + void attach_asserted_held(Callback<void()> function); + + template<typename T, typename M> + void attach_asserted_held(T *obj, M method){ + core_util_critical_section_enter(); + attach_asserted_held(callback(obj, method)); + core_util_critical_section_exit(); + } + + void attach_deasserted_held(Callback<void()> function); + + template<typename T, typename M> + void attach_deasserted_held(T *obj, M method){ + core_util_critical_section_enter(); + attach_deasserted_held(callback(obj, method)); + core_util_critical_section_exit(); + } + + /** operator int() + * + * Read the value of the pin being sampled. + */ + operator int() { + return _in->read(); + } + +protected: DigitalIn *_in; Ticker *_ticker; int _prevState; @@ -140,358 +164,21 @@ int _samplesTillAssert; int _samplesTillHeldReload; int _samplesTillHeld; - FunctionPointer _callbackAsserted; - FunctionPointer _callbackDeasserted; - FunctionPointer _callbackAssertedHeld; - FunctionPointer _callbackDeassertedHeld; + Callback<void()> _callbackAsserted; + Callback<void()> _callbackDeasserted; + Callback<void()> _callbackAssertedHeld; + Callback<void()> _callbackDeassertedHeld; + + /** The Ticker periodic callback function + */ + void isr(void); /** initialise class * * @param PinName p is a valid pin that supports DigitalIn * @param PinMode m The mode the DigitalIn should use. */ - void init(PinName p, PinMode m) { - _sampleTime = PINDETECT_SAMPLE_PERIOD; - _samplesTillAssert = PINDETECT_ASSERT_COUNT; - _samplesTillHeld = 0; - _samplesTillAssertReload = PINDETECT_ASSERT_COUNT; - _samplesTillHeldReload = PINDETECT_HOLD_COUNT; - _assertValue = PINDETECT_PIN_ASSTERED; - - _in = new DigitalIn( p ); - _in->mode( m ); - _prevState = _in->read(); - _ticker = new Ticker; - } - -public: - - friend class Ticker; - - PinDetect() { error("You must supply a PinName"); } - - /** PinDetect constructor - * - * By default the PinMode is set to PullDown. - * - * @see http://mbed.org/handbook/DigitalIn - * @param p PinName is a valid pin that supports DigitalIn - */ - PinDetect(PinName p) { - init( p, PullDefault ); - } - - /** PinDetect constructor - * - * @see http://mbed.org/handbook/DigitalIn - * @param PinName p is a valid pin that supports DigitalIn - * @param PinMode m The mode the DigitalIn should use. - */ - PinDetect(PinName p, PinMode m) { - init( p, m ); - } - - /** PinDetect destructor - */ - ~PinDetect() { - if ( _ticker ) delete( _ticker ); - if ( _in ) delete( _in ); - } - - /** Set the sampling time in microseconds. - * - * @param int The time between pin samples in microseconds. - */ - void setSampleFrequency(int i = PINDETECT_SAMPLE_PERIOD) { - _sampleTime = i; - _prevState = _in->read(); - _ticker->attach_us( this, &PinDetect::isr, _sampleTime ); - } - - /** Set the value used as assert. - * - * Defaults to 1 (ie if pin == 1 then pin asserted). - * - * @param int New assert value (1 or 0) - */ - void setAssertValue (int i = PINDETECT_PIN_ASSTERED) { _assertValue = i & 1; } - - /** Set the number of continuous samples until assert assumed. - * - * Defaults to 1 (1 * sample frequency). - * - * @param int The number of continuous samples until assert assumed. - */ - void setSamplesTillAssert(int i) { _samplesTillAssertReload = i; } - - /** Set the number of continuous samples until held assumed. - * - * Defaults to 50 * sample frequency. - * - * @param int The number of continuous samples until held assumed. - */ - void setSamplesTillHeld(int i) { _samplesTillHeldReload = i; } - - /** Set the pin mode. - * - * @see http://mbed.org/projects/libraries/api/mbed/trunk/DigitalInOut#DigitalInOut.mode - * @param PinMode m The mode to pass on to the DigitalIn - */ - void mode(PinMode m) { _in->mode( m ); } - - /** Attach a callback function - * - * @code - * - * DigitalOut led1( LED1 ); - * PinDetect pin( p30 ); - * - * void myCallback( void ) { - * led1 = 1; - * }; - * - * main() { - * pin.attach_asserted( &myCallback ); - * } - * - * @endcode - * - * Call this function when a pin is asserted. - * @param function A C function pointer - */ - void attach_asserted(void (*function)(void)) { - _callbackAsserted.attach( function ); - } - - /** Attach a callback object/method - * - * @code - * - * class Bar { - * public: - * void myCallback( void ) { led1 = 1; } - * }; - * - * DigitalOut led1( LED1 ); - * PinDetect pin( p30 ); - * Bar bar; - * - * main() { - * pin.attach_asserted( &bar, &Bar::myCallback ); - * } - * - * @endcode - * - * Call this function when a pin is asserted. - * @param object An object that conatins the callback method. - * @param method The method within the object to call. - */ - template<typename T> - void attach_asserted(T *object, void (T::*member)(void)) { - _callbackAsserted.attach( object, member ); - } - - /** Attach a callback function - * - * @code - * - * DigitalOut led1( LED1 ); - * PinDetect pin( p30 ); - * - * void myCallback( void ) { - * led1 = 0; - * }; - * - * main() { - * pin.attach_deasserted( &myCallback ); - * } - * - * @endcode - * - * Call this function when a pin is deasserted. - * @param function A C function pointer - */ - void attach_deasserted(void (*function)(void)) { - _callbackDeasserted.attach( function ); - } - - /** Attach a callback object/method - * - * @code - * - * class Bar { - * public: - * void myCallback( void ) { led1 = 0; } - * }; - * - * DigitalOut led1( LED1 ); - * PinDetect pin( p30 ); - * Bar bar; - * - * main() { - * pin.attach_deasserted( &bar, &Bar::myCallback ); - * } - * - * @endcode - * - * Call this function when a pin is deasserted. - * @param object An object that conatins the callback method. - * @param method The method within the object to call. - */ - template<typename T> - void attach_deasserted(T *object, void (T::*member)(void)) { - _callbackDeasserted.attach( object, member ); - } - - /** Attach a callback function - * - * @code - * - * DigitalOut led2( LED2 ); - * PinDetect pin( p30 ); - * - * void myCallback( void ) { - * led2 = 1; - * }; - * - * main() { - * pin.attach_asserted_held( &myCallback ); - * } - * - * @endcode - * - * Call this function when a pin is asserted and held. - * @param function A C function pointer - */ - void attach_asserted_held(void (*function)(void)) { - _callbackAssertedHeld.attach( function ); - } - - /** Attach a callback object/method - * - * @code - * - * class Bar { - * public: - * void myCallback( void ) { led2 = 0; } - * }; - * - * DigitalOut led2( LED2 ); - * PinDetect pin( p30 ); - * Bar bar; - * - * main() { - * pin.attach_asserted_held( &bar, &Bar::myCallback ); - * } - * - * @endcode - * - * Call this function when a pin is asserted and held. - * @param object An object that conatins the callback method. - * @param method The method within the object to call. - */ - template<typename T> - void attach_asserted_held(T *object, void (T::*member)(void)) { - _callbackAssertedHeld.attach( object, member ); - } - - /** Attach a callback function - * - * @code - * - * DigitalOut led3( LED3 ); - * PinDetect pin( p30 ); - * - * void myCallback( void ) { - * led3 = 1; - * }; - * - * main() { - * pin.attach_deasserted_held( &myCallback ); - * } - * - * @endcode - * - * Call this function when a pin is deasserted and held. - * @param function A C function pointer - */ - void attach_deasserted_held(void (*function)(void)) { - _callbackDeassertedHeld.attach( function ); - } - - /** Attach a callback object/method - * - * @code - * - * class Bar { - * public: - * void myCallback( void ) { led3 = 0; } - * }; - * - * DigitalOut led3( LED3 ); - * PinDetect pin( p30 ); - * Bar bar; - * - * main() { - * pin.attach_deasserted_held( &bar, &Bar::myCallback ); - * } - * - * @endcode - * - * Call this function when a pin is deasserted and held. - * @param object An object that conatins the callback method. - * @param method The method within the object to call. - */ - template<typename T> - void attach_deasserted_held(T *object, void (T::*member)(void)) { - _callbackDeassertedHeld.attach( object, member ); - } - - /** operator int() - * - * Read the value of the pin being sampled. - */ - operator int() { return _in->read(); } - -protected: - /** The Ticker periodic callback function - */ - void isr(void) { - int currentState = _in->read(); - - if ( currentState != _prevState ) { - if ( _samplesTillAssert == 0 ) { - _prevState = currentState; - _samplesTillHeld = _samplesTillHeldReload; - if ( currentState == _assertValue ) - _callbackAsserted.call(); - else - _callbackDeasserted.call(); - } - else { - _samplesTillAssert--; - } - } - else { - _samplesTillAssert = _samplesTillAssertReload; - } - - if ( _samplesTillHeld ) { - if ( _prevState == currentState ) { - _samplesTillHeld--; - if ( _samplesTillHeld == 0 ) { - if ( currentState == _assertValue ) - _callbackAssertedHeld.call(); - else - _callbackDeassertedHeld.call(); - } - } - else { - _samplesTillHeld = 0; - } - } - } - + void init(PinName p, PinMode m); }; }; // namespace AjK ends.