MTDOT-BOX-EVB-Factory-Firmware

Dependencies:   NCP5623B GpsParser ISL29011 libmDot-mbed5 MTS-Serial MMA845x DOGS102 MPL3115A2

Revision:
1:71125aa00e33
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ButtonHandler/ButtonHandler.cpp	Thu Feb 04 12:36:36 2016 -0600
@@ -0,0 +1,156 @@
+/* Copyright (c) <2016> <MultiTech Systems>, MIT License
+ *
+ * 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 "ButtonHandler.h"
+
+#define signal (int32_t)0xA0
+
+typedef enum {
+    b_none = 0,
+    b_sw1_fall,
+    b_sw1_rise,
+    b_sw2_fall,
+    b_sw2_rise
+} InternalButtonEvent;
+
+InternalButtonEvent event = b_none;
+bool check_sw1 = false;
+
+void b_worker(void const* argument) {
+    ButtonHandler* b = (ButtonHandler*)argument;
+    osEvent e;
+
+    while (true) {
+        e = Thread::signal_wait(signal, 250);
+        if (e.status == osEventSignal) {
+            switch (event) {
+                case b_sw1_fall:
+                    if (! b->_sw1_running) {
+                        check_sw1 = true;
+                        b->_sw1_running = true;
+                        b->_sw1_timer.reset();
+                        b->_sw1_timer.start();
+                    }
+                    break;
+                
+                case b_sw1_rise:
+                    if (b->_sw1_running) {
+                        check_sw1 = false;
+                        b->_sw1_running = false;
+                        b->_sw1_timer.stop();
+                        b->_sw1_time = b->_sw1_timer.read_ms();
+
+                        if (b->_sw1_time > b->_debounce_time) {
+                            b->_event = ButtonHandler::sw1_press;
+                            osSignalSet(b->_main, buttonSignal);
+                        }
+                    }
+                    break;
+
+                case b_sw2_fall:
+                    if (! b->_sw2_running) {
+                        b->_sw2_running = true;
+                        b->_sw2_timer.reset();
+                        b->_sw2_timer.start();
+                    }
+                    break;
+
+                case b_sw2_rise:
+                    if (b->_sw2_running) {
+                        b->_sw2_running = false;
+                        b->_sw2_timer.stop();
+                        b->_sw2_time = b->_sw2_timer.read_ms();
+
+                        if (b->_sw2_time > b->_debounce_time) {
+                            b->_event = ButtonHandler::sw2_press;
+                            osSignalSet(b->_main, buttonSignal);
+                        }
+                    }
+                    break;
+
+                default:
+                    break;
+            }
+        }
+
+        if (check_sw1) {
+            if (b->_sw1_timer.read_ms() > b->_hold_threshold) {
+                check_sw1 = false;
+                b->_sw1_running = false;
+                b->_sw1_timer.stop();
+                b->_event = ButtonHandler::sw1_hold;
+                osSignalSet(b->_main, buttonSignal);
+            }
+        }
+    }
+}
+
+ButtonHandler::ButtonHandler(osThreadId main)
+  : _main(main),
+    _thread(b_worker, (void*)this),
+    _sw1(PA_12),
+    _sw2(PA_11),
+    _sw1_time(0),
+    _sw2_time(0),
+    _sw1_running(false),
+    _sw2_running(false),
+    _event(none),
+    _debounce_time(20),
+    _hold_threshold(500)
+{
+    // fall handler called on press, rise handler called on release
+    _sw1.fall(this, &ButtonHandler::sw1_fall);
+    _sw1.rise(this, &ButtonHandler::sw1_rise);
+    // need to set mode to PullUp after attaching handlers - default is PullNone (see PinNames.h)
+    _sw1.mode(PullUp);
+
+    _sw2.fall(this, &ButtonHandler::sw2_fall);
+    _sw2.rise(this, &ButtonHandler::sw2_rise);
+    _sw2.mode(PullUp);
+}
+
+ButtonHandler::ButtonEvent ButtonHandler::getButtonEvent() {
+    ButtonEvent event = _event;
+    _event = none;
+    return event;
+}
+
+void ButtonHandler::sw1_fall() {
+    event = b_sw1_fall;
+    _thread.signal_set(signal);
+    _thread.signal_clr(signal);
+}
+
+void ButtonHandler::sw1_rise() {
+    event = b_sw1_rise;
+    _thread.signal_set(signal);
+    _thread.signal_clr(signal);
+}
+
+void ButtonHandler::sw2_fall() {
+    event = b_sw2_fall;
+    _thread.signal_set(signal);
+    _thread.signal_clr(signal);
+}
+
+void ButtonHandler::sw2_rise() {
+    event = b_sw2_rise;
+    _thread.signal_set(signal);
+    _thread.signal_clr(signal);
+}
+