Implementation of a button class and test program

Committer:
JMF
Date:
Thu Aug 30 00:35:30 2018 +0000
Revision:
0:377a50b631cf
Child:
1:c668e9604e63
button class example

Who changed what in which revision?

UserRevisionLine numberNew contents of line
JMF 0:377a50b631cf 1 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
JMF 0:377a50b631cf 2
JMF 0:377a50b631cf 3 #include "mbed.h"
JMF 0:377a50b631cf 4
JMF 0:377a50b631cf 5 #define BUTTON_DEBOUNCE 20
JMF 0:377a50b631cf 6
JMF 0:377a50b631cf 7 class Button {
JMF 0:377a50b631cf 8 protected:
JMF 0:377a50b631cf 9 InterruptIn user_button;
JMF 0:377a50b631cf 10 void (*br_cb)(int);
JMF 0:377a50b631cf 11 void (*bp_cb)(void);
JMF 0:377a50b631cf 12
JMF 0:377a50b631cf 13 Thread button_thread;
JMF 0:377a50b631cf 14 void button_monitor_task(void);
JMF 0:377a50b631cf 15 EventQueue button_queue;
JMF 0:377a50b631cf 16 uint64_t bp_time, bp_duration;
JMF 0:377a50b631cf 17 int button_pressed;
JMF 0:377a50b631cf 18
JMF 0:377a50b631cf 19 void button_press_handler(void) {
JMF 0:377a50b631cf 20 if( (rtos::Kernel::get_ms_count() - bp_time) < BUTTON_DEBOUNCE)
JMF 0:377a50b631cf 21 return;
JMF 0:377a50b631cf 22 bp_time = rtos::Kernel::get_ms_count();
JMF 0:377a50b631cf 23 if( bp_cb )
JMF 0:377a50b631cf 24 bp_cb();
JMF 0:377a50b631cf 25 }
JMF 0:377a50b631cf 26
JMF 0:377a50b631cf 27 void button_release_handler(void) {
JMF 0:377a50b631cf 28 uint64_t tmp = rtos::Kernel::get_ms_count() - bp_time;
JMF 0:377a50b631cf 29 if( tmp > BUTTON_DEBOUNCE ) {
JMF 0:377a50b631cf 30 bp_duration = tmp;
JMF 0:377a50b631cf 31 button_pressed++;
JMF 0:377a50b631cf 32 if( br_cb )
JMF 0:377a50b631cf 33 br_cb(bp_duration);
JMF 0:377a50b631cf 34 }
JMF 0:377a50b631cf 35 }
JMF 0:377a50b631cf 36
JMF 0:377a50b631cf 37 public:
JMF 0:377a50b631cf 38 enum State { ActiveHigh = 0, ActiveLow };
JMF 0:377a50b631cf 39
JMF 0:377a50b631cf 40 Button(PinName p, State s, void (*cb)(int)=NULL) :
JMF 0:377a50b631cf 41 user_button(p),
JMF 0:377a50b631cf 42 br_cb(cb),
JMF 0:377a50b631cf 43 bp_cb(NULL),
JMF 0:377a50b631cf 44 bp_time(0),
JMF 0:377a50b631cf 45 bp_duration(0),
JMF 0:377a50b631cf 46 button_pressed(0)
JMF 0:377a50b631cf 47 {
JMF 0:377a50b631cf 48 // The user button is active low so setup the falling edge to generate
JMF 0:377a50b631cf 49 // an interrupt. Catch the release with an event queue event
JMF 0:377a50b631cf 50 button_thread.start(callback(&button_queue, &EventQueue::dispatch_forever));
JMF 0:377a50b631cf 51 if( s == ActiveHigh ) {
JMF 0:377a50b631cf 52 user_button.rise( Callback<void()>(this, &Button::button_press_handler) );
JMF 0:377a50b631cf 53 user_button.fall( button_queue.event( Callback<void()>(this, &Button::button_release_handler)));
JMF 0:377a50b631cf 54 }
JMF 0:377a50b631cf 55 else{
JMF 0:377a50b631cf 56 user_button.fall( Callback<void()>(this, &Button::button_press_handler) );
JMF 0:377a50b631cf 57 user_button.rise(button_queue.event(Callback<void()>(this, &Button::button_release_handler)));
JMF 0:377a50b631cf 58 }
JMF 0:377a50b631cf 59 }
JMF 0:377a50b631cf 60
JMF 0:377a50b631cf 61 int chkButton_press(int *duration) {
JMF 0:377a50b631cf 62 int bp = button_pressed;
JMF 0:377a50b631cf 63
JMF 0:377a50b631cf 64 if( button_pressed ) {
JMF 0:377a50b631cf 65 *duration = bp_duration;
JMF 0:377a50b631cf 66 bp_duration = 0;
JMF 0:377a50b631cf 67 button_pressed = 0;
JMF 0:377a50b631cf 68 }
JMF 0:377a50b631cf 69 return bp;
JMF 0:377a50b631cf 70 }
JMF 0:377a50b631cf 71
JMF 0:377a50b631cf 72 void setButton_press_cb( void (*buttonpresscb)(void) ) {
JMF 0:377a50b631cf 73 bp_cb = buttonpresscb;
JMF 0:377a50b631cf 74 }
JMF 0:377a50b631cf 75 };