Mbed OS 5

Fork of PinDetect by Arturo Alvarado

Rewritten to Mbed OS 5 and their callback mechanism

Revision:
4:bacc386fe2ad
Child:
5:2b0afd293d1d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PinDetect.cpp	Wed Nov 16 23:20:29 2016 +0000
@@ -0,0 +1,155 @@
+/*
+    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.
+*/
+
+#include "PinDetect.h"
+
+namespace AjK {
+
+static void donothing() {}
+    
+PinDetect::PinDetect(PinName p) : _callbackAsserted(),
+                                  _callbackDeasserted(),
+                                  _callbackAssertedHeld(),
+                                  _callbackDeassertedHeld() {
+    init( p, PullDefault );
+    _callbackAsserted.attach(donothing);
+    _callbackDeasserted.attach(donothing);
+    _callbackAssertedHeld.attach(donothing);
+    _callbackDeassertedHeld.attach(donothing);
+}
+
+PinDetect::PinDetect(PinName p, PinMode m) : _callbackAsserted(),
+                                             _callbackDeasserted(),
+                                             _callbackAssertedHeld(),
+                                             _callbackDeassertedHeld() {
+    init( p, m );
+    _callbackAsserted.attach(donothing);
+    _callbackDeasserted.attach(donothing);
+    _callbackAssertedHeld.attach(donothing);
+    _callbackDeassertedHeld.attach(donothing);
+}
+
+
+PinDetect::~PinDetect(void){
+    if ( _ticker )  delete( _ticker );
+    if ( _in )      delete( _in );
+}
+
+void PinDetect::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;
+}
+
+void PinDetect::setSampleFrequency(int i) { 
+    _sampleTime = i; 
+    _prevState  = _in->read();        
+    _ticker->attach_us(callback(this, &PinDetect::isr), _sampleTime );
+}
+
+void PinDetect::setAssertValue (int i) {
+    _assertValue = i & 1;
+}
+
+void PinDetect::setSamplesTillAssert(int i) {
+    _samplesTillAssertReload = i;
+}
+
+void PinDetect::setSamplesTillHeld(int i) {
+    _samplesTillHeldReload = i;
+}
+
+void PinDetect::mode(PinMode m) {
+    _in->mode( m );
+}
+
+void PinDetect::attach_asserted(Callback<void()> function) {
+    core_util_critical_section_enter();
+    _callbackAsserted.attach( function );
+    core_util_critical_section_exit();
+}
+
+void PinDetect::attach_deasserted(Callback<void()> function) {
+    core_util_critical_section_enter();
+    _callbackDeasserted.attach( function );
+    core_util_critical_section_exit();
+}
+
+void PinDetect::attach_asserted_held(Callback<void()> function) {
+    core_util_critical_section_enter();
+    _callbackAssertedHeld.attach( function );
+    core_util_critical_section_exit();
+}
+
+void PinDetect::attach_deasserted_held(Callback<void()> function) {
+    core_util_critical_section_enter();
+    _callbackDeassertedHeld.attach( function );
+    core_util_critical_section_exit();
+}
+
+void PinDetect::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;
+        }
+    }
+}
+}; // namespace AjK ends.
+
+using namespace AjK;
+