Jim Flynn / Mbed OS button_class_and_test
Revision:
0:377a50b631cf
Child:
1:c668e9604e63
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Button.hpp	Thu Aug 30 00:35:30 2018 +0000
@@ -0,0 +1,75 @@
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include "mbed.h"
+
+#define BUTTON_DEBOUNCE           20
+
+class Button {
+    protected:
+        InterruptIn user_button;
+        void (*br_cb)(int);
+        void (*bp_cb)(void);
+
+        Thread      button_thread;
+        void        button_monitor_task(void);
+        EventQueue  button_queue;
+        uint64_t    bp_time, bp_duration;
+        int         button_pressed;
+
+        void button_press_handler(void) {
+            if( (rtos::Kernel::get_ms_count() - bp_time) < BUTTON_DEBOUNCE)
+                return;
+            bp_time = rtos::Kernel::get_ms_count();
+            if( bp_cb )
+                bp_cb();
+        }
+
+        void button_release_handler(void) {
+            uint64_t tmp = rtos::Kernel::get_ms_count() - bp_time;
+            if( tmp > BUTTON_DEBOUNCE ) {
+                bp_duration = tmp;
+                button_pressed++;
+                if( br_cb )
+                  br_cb(bp_duration);
+                }
+        }
+
+    public:
+        enum State { ActiveHigh = 0, ActiveLow };
+
+        Button(PinName p, State s, void (*cb)(int)=NULL) : 
+            user_button(p),
+            br_cb(cb),
+            bp_cb(NULL),
+            bp_time(0),
+            bp_duration(0),
+            button_pressed(0)
+            {
+            // The user button is active low so setup the falling edge to generate
+            // an interrupt. Catch the release with an event queue event
+            button_thread.start(callback(&button_queue, &EventQueue::dispatch_forever));
+            if( s == ActiveHigh ) {
+                user_button.rise( Callback<void()>(this, &Button::button_press_handler) ); 
+                user_button.fall( button_queue.event( Callback<void()>(this, &Button::button_release_handler)));
+                }
+            else{
+                user_button.fall( Callback<void()>(this, &Button::button_press_handler) );
+                user_button.rise(button_queue.event(Callback<void()>(this, &Button::button_release_handler)));
+                }
+            }
+
+        int chkButton_press(int *duration) {
+            int bp = button_pressed;
+        
+            if( button_pressed ) {
+                *duration = bp_duration;
+                bp_duration = 0;
+                button_pressed = 0;
+                }
+            return bp;
+            }
+            
+        void setButton_press_cb( void (*buttonpresscb)(void) ) {
+            bp_cb = buttonpresscb;
+            }
+};