Factory firmware for the MultiTech Dotbox (MTDOT-BOX) and EVB (MTDOT-EVB) products.

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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ButtonHandler.cpp Source File

ButtonHandler.cpp

00001 /* Copyright (c) <2016> <MultiTech Systems>, MIT License
00002  *
00003  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 
00004  * and associated documentation files (the "Software"), to deal in the Software without restriction, 
00005  * including without limitation the rights to use, copy, modify, merge, publish, distribute, 
00006  * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 
00007  * furnished to do so, subject to the following conditions:
00008  *
00009  * The above copyright notice and this permission notice shall be included in all copies or 
00010  * substantial portions of the Software.
00011  *
00012  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 
00013  * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
00014  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
00015  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
00016  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00017  */
00018 
00019 #include "ButtonHandler.h"
00020 
00021 #define signal (int32_t)0xA0
00022 
00023 typedef enum {
00024     b_none = 0,
00025     b_sw1_fall,
00026     b_sw1_rise,
00027     b_sw2_fall,
00028     b_sw2_rise
00029 } InternalButtonEvent;
00030 
00031 InternalButtonEvent event = b_none;
00032 bool check_sw1 = false;
00033 
00034 void b_worker(void const* argument) {
00035     ButtonHandler* b = (ButtonHandler*)argument;
00036     osEvent e;
00037 
00038     while (true) {
00039         e = Thread::signal_wait(signal, 250);
00040         if (e.status == osEventSignal) {
00041             switch (event) {
00042                 case b_sw1_fall:
00043                     if (! b->_sw1_running) {
00044                         check_sw1 = true;
00045                         b->_sw1_running = true;
00046                         b->_sw1_timer.reset();
00047                         b->_sw1_timer.start();
00048                     }
00049                     break;
00050                 
00051                 case b_sw1_rise:
00052                     if (b->_sw1_running) {
00053                         check_sw1 = false;
00054                         b->_sw1_running = false;
00055                         b->_sw1_timer.stop();
00056                         b->_sw1_time = b->_sw1_timer.read_ms();
00057 
00058                         if (b->_sw1_time > b->_debounce_time) {
00059                             b->_event = ButtonHandler::sw1_press;
00060                             osSignalSet(b->_main, buttonSignal);
00061                         }
00062                     }
00063                     break;
00064 
00065                 case b_sw2_fall:
00066                     if (! b->_sw2_running) {
00067                         b->_sw2_running = true;
00068                         b->_sw2_timer.reset();
00069                         b->_sw2_timer.start();
00070                     }
00071                     break;
00072 
00073                 case b_sw2_rise:
00074                     if (b->_sw2_running) {
00075                         b->_sw2_running = false;
00076                         b->_sw2_timer.stop();
00077                         b->_sw2_time = b->_sw2_timer.read_ms();
00078 
00079                         if (b->_sw2_time > b->_debounce_time) {
00080                             b->_event = ButtonHandler::sw2_press;
00081                             osSignalSet(b->_main, buttonSignal);
00082                         }
00083                     }
00084                     break;
00085 
00086                 default:
00087                     break;
00088             }
00089         }
00090 
00091         if (check_sw1) {
00092             if (b->_sw1_timer.read_ms() > b->_hold_threshold) {
00093                 check_sw1 = false;
00094                 b->_sw1_running = false;
00095                 b->_sw1_timer.stop();
00096                 b->_event = ButtonHandler::sw1_hold;
00097                 osSignalSet(b->_main, buttonSignal);
00098             }
00099         }
00100     }
00101 }
00102 
00103 ButtonHandler::ButtonHandler(osThreadId main)
00104   : _main(main),
00105     _thread(b_worker, (void*)this),
00106     _sw1(PA_12),
00107     _sw2(PA_11),
00108     _sw1_time(0),
00109     _sw2_time(0),
00110     _sw1_running(false),
00111     _sw2_running(false),
00112     _event(none),
00113     _debounce_time(20),
00114     _hold_threshold(500)
00115 {
00116     // fall handler called on press, rise handler called on release
00117     _sw1.fall(this, &ButtonHandler::sw1_fall);
00118     _sw1.rise(this, &ButtonHandler::sw1_rise);
00119     // need to set mode to PullUp after attaching handlers - default is PullNone (see PinNames.h)
00120     _sw1.mode(PullUp);
00121 
00122     _sw2.fall(this, &ButtonHandler::sw2_fall);
00123     _sw2.rise(this, &ButtonHandler::sw2_rise);
00124     _sw2.mode(PullUp);
00125 }
00126 
00127 ButtonHandler::ButtonEvent ButtonHandler::getButtonEvent() {
00128     ButtonEvent event = _event;
00129     _event = none;
00130     return event;
00131 }
00132 
00133 void ButtonHandler::sw1_fall() {
00134     event = b_sw1_fall;
00135     _thread.signal_set(signal);
00136     _thread.signal_clr(signal);
00137 }
00138 
00139 void ButtonHandler::sw1_rise() {
00140     event = b_sw1_rise;
00141     _thread.signal_set(signal);
00142     _thread.signal_clr(signal);
00143 }
00144 
00145 void ButtonHandler::sw2_fall() {
00146     event = b_sw2_fall;
00147     _thread.signal_set(signal);
00148     _thread.signal_clr(signal);
00149 }
00150 
00151 void ButtonHandler::sw2_rise() {
00152     event = b_sw2_rise;
00153     _thread.signal_set(signal);
00154     _thread.signal_clr(signal);
00155 }
00156