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

Fork of PinDetect by Andy K

Revision:
4:3aca44118b7a
Parent:
3:5ff38909c179
--- a/PinDetect.h	Wed May 06 21:29:16 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,525 +0,0 @@
-/*
-    Copyright (c) 2010 Andy Kirkham
- 
-    Permission is hereby granted, free of charge, to any person obtaining a copy
-    of this software and associated documentation files (the "Software"), to deal
-    in the Software without restriction, including without limitation the rights
-    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-    copies of the Software, and to permit persons to whom the Software is
-    furnished to do so, subject to the following conditions:
- 
-    The above copyright notice and this permission notice shall be included in
-    all copies or substantial portions of the Software.
- 
-    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-    THE SOFTWARE.
-*/
-
-#ifndef AJK_PIN_DETECT_H
-#define AJK_PIN_DETECT_H
-
-#ifndef MBED_H
-#include "mbed.h"
-#endif
-
-#ifndef PINDETECT_PIN_ASSTERED
-#define PINDETECT_PIN_ASSTERED   1
-#endif
-
-#ifndef PINDETECT_SAMPLE_PERIOD
-#define PINDETECT_SAMPLE_PERIOD 20000
-#endif
-
-#ifndef PINDETECT_ASSERT_COUNT  
-#define PINDETECT_ASSERT_COUNT  1
-#endif
-
-#ifndef PINDETECT_PINSTATES
-#define PINDETECT_PINSTATES
-
-// pin state bitmask
-#define S_IDLE          0
-#define S_RINGING       ((uint32_t)1<<0)
-#define S_ASSERTED      ((uint32_t)1<<1)
-#define S_HELD          ((uint32_t)1<<2)
-
-
-#endif
-
-/** 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 {
-
-
-    
-public:
-
-    /** 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, PinMode m, int assertvalue, unsigned int debounce_us, unsigned int held_us): interr(p), _assertvalue(assertvalue)
-    {
-        debouncetime=debounce_us;
-        heldtime=held_us;
-        bouncein=0;
-        bounceout=0;
-        disable();
-        if (_assertvalue) {   // pulse up
-            interr.rise(this, &PinDetect::startpulse); // first rise then fall
-            interr.fall(this, &PinDetect::endpulse);
-
-        } else {   // pulse down
-            interr.fall(this, &PinDetect::startpulse); // first fall then rise
-            interr.rise(this, &PinDetect::endpulse);
-        }
-        interr.mode(m);
-        statereset(); // pinstate=S_IDLE;
-        trig=false;
-        enable();
-    }
-    
-    /** PinDetect destructor
-     */    
-    ~PinDetect() {
-        interr.disable_irq();
-        timeoutbounce.detach();
-        timeoutheld.detach();
-    }
-    
-    void disable()
-    {
-        interr.disable_irq();
-        statereset();
-    }
-    void enable()
-    {
-        interr.enable_irq();
-        statereset();
-    }
-    
-    /** 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 setDebounceTime(int i) { debouncetime = 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 setHeldTime(int i) { heldtime = i; }
-
-    
-    /** 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 interr.read(); }
-    
-    /** Get the current pin state
-     *
-     * @return pinstate bitmask S_HELD|S_ASSERTED|S_RINGING, 0=S_IDLE
-     */
-    unsigned int state()
-    {
-        return pinstate;
-    }
-    
-    /** Reset pinstate to S_IDLE and reset debounce/held timers 
-     *
-     * @return pinstate bitmask S_HELD|S_ASSERTED|S_RINGING, 0=S_IDLE
-     */
-    void statereset()
-    {
-        pinstate=S_IDLE;
-        timeoutheld.detach();
-        timeoutbounce.detach();
-        pinstate=S_IDLE;
-    }
-    unsigned int getbouncein()
-    {
-        return bouncein;
-    }
-    unsigned int getbounceout()
-    {
-        return bounceout;
-    }
-
-protected:
-
-    void startpulse()
-    {
-        pinstate|=S_RINGING;
-        if((pinstate&S_ASSERTED)==0) timeoutbounce.attach_us(this, &PinDetect::onasserted, debouncetime);
-        // else if state is asserted and we are here, it means we are debouncing transition to deasserted, timeout is already attached to ondeasserted()
-        trig=true;  // ISR completed
-    }
-
-    void endpulse()
-    {
-        if(!trig) return; // first check if the previous startpulse ISR completed
-        pinstate|=S_RINGING;
-        
-        if((pinstate&S_ASSERTED)!=0) // if was asserted or held asserted, debounce transition to deasserted
-        {
-            timeoutheld.detach();
-            timeoutbounce.attach_us(this, &PinDetect::ondeasserted, debouncetime);
-        }
-        trig=false;
-    }
-    
-    void onasserted()
-    {
-        if(interr.read()!=_assertvalue)
-        {
-            bouncein++;
-            return; // was a bounce
-        }
-        pinstate|=S_ASSERTED; // set asserted
-        pinstate&= ~(S_RINGING|S_HELD); // clear ringing and held
-        timeoutheld.attach_us(this, &PinDetect::onheld, heldtime);
-        callbackAsserted.call(); // call function for pin state change (deasserted -> asserted)
-    }
-    
-    void onheld()
-    {
-        if((pinstate&S_RINGING)!=0 || (pinstate&S_ASSERTED)==0 || (interr.read()!=_assertvalue)) return; // to be valid, needs ringing=false asserted=true pinread=assertvalue
-        pinstate|=S_HELD; // set held
-        callbackAssertedHeld.call(); // call function for pin state change (asserted -> held asserted)
-    }
-    
-    void ondeasserted()
-    {
-        if((pinstate&(S_ASSERTED))==0) return; // pinstate was reset externally
-        if(interr.read()==_assertvalue)
-        {
-            bounceout++;
-            return; // was a bounce
-        }
-        if((pinstate&S_HELD)==0) callbackDeasserted.call(); // call function for pin state change (asserted -> deasserted)(quick pulse)
-        else callbackDeassertedHeld.call(); // call function for pin state change (held asserted -> deasserted)(long pulse)
-        pinstate=S_IDLE;
-    }
-    
-private:
-    InterruptIn interr;
-    Timeout      timeoutbounce;
-    Timeout      timeoutheld;
-    unsigned int debouncetime;
-    unsigned int heldtime;
-    int         _assertvalue;
-    FunctionPointer callbackAsserted;
-    FunctionPointer callbackDeasserted;
-    FunctionPointer callbackAssertedHeld;
-    FunctionPointer callbackDeassertedHeld;
-    volatile unsigned int pinstate;
-    volatile unsigned int bouncein;
-    volatile unsigned int bounceout;
-    
-    bool trig;
-    
-};
-
-
-#endif