Eddystone test using modified DAL

Dependencies:   BLE_API mbed-dev-bin nRF51822

Dependents:   microbit-eddystone

Fork of microbit-dal by Lancaster University

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MicroBitMultiButton.cpp Source File

MicroBitMultiButton.cpp

00001 /*
00002 The MIT License (MIT)
00003 
00004 Copyright (c) 2016 British Broadcasting Corporation.
00005 This software is provided by Lancaster University by arrangement with the BBC.
00006 
00007 Permission is hereby granted, free of charge, to any person obtaining a
00008 copy of this software and associated documentation files (the "Software"),
00009 to deal in the Software without restriction, including without limitation
00010 the rights to use, copy, modify, merge, publish, distribute, sublicense,
00011 and/or sell copies of the Software, and to permit persons to whom the
00012 Software is furnished to do so, subject to the following conditions:
00013 
00014 The above copyright notice and this permission notice shall be included in
00015 all copies or substantial portions of the Software.
00016 
00017 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00018 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00019 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
00020 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00021 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
00022 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
00023 DEALINGS IN THE SOFTWARE.
00024 */
00025 
00026 /**
00027   * Class definition for MicroBitMultiButton.
00028   *
00029   * Represents a virtual button, capable of reacting to simultaneous presses of two
00030   * other buttons.
00031   */
00032 #include "MicroBitConfig.h"
00033 #include "MicroBitMultiButton.h"
00034 
00035 /**
00036   * Constructor.
00037   *
00038   * Create a representation of a virtual button, that generates events based upon the combination
00039   * of two given buttons.
00040   *
00041   * @param button1 the unique ID of the first button to watch.
00042   *
00043   * @param button2 the unique ID of the second button to watch.
00044   *
00045   * @param id the unique EventModel id of this MicroBitMultiButton instance.
00046   *
00047   * @code
00048   * multiButton(MICROBIT_ID_BUTTON_A, MICROBIT_ID_BUTTON_B, MICROBIT_ID_BUTTON_AB);
00049   * @endcode
00050   */
00051 MicroBitMultiButton::MicroBitMultiButton(uint16_t button1, uint16_t button2, uint16_t id)
00052 {
00053     this->id = id;
00054     this->button1 = button1;
00055     this->button2 = button2;
00056     this->eventConfiguration = MICROBIT_BUTTON_SIMPLE_EVENTS;
00057 
00058     if (EventModel::defaultEventBus)
00059     {
00060         EventModel::defaultEventBus->listen(button1, MICROBIT_EVT_ANY, this, &MicroBitMultiButton::onButtonEvent,  MESSAGE_BUS_LISTENER_IMMEDIATE);
00061         EventModel::defaultEventBus->listen(button2, MICROBIT_EVT_ANY, this, &MicroBitMultiButton::onButtonEvent,  MESSAGE_BUS_LISTENER_IMMEDIATE);
00062     }
00063 }
00064 
00065 /**
00066   * Retrieves the button id for the alternate button id given.
00067   *
00068   * @param b the id of the button whose state we would like to retrieve.
00069   *
00070   * @return the other sub button id.
00071   */
00072 uint16_t MicroBitMultiButton::otherSubButton(uint16_t b)
00073 {
00074     return (b == button1 ? button2 : button1);
00075 }
00076 
00077 /**
00078   * Determines if the given button id is marked as pressed.
00079   *
00080   * @param button the id of the button whose state we would like to retrieve.
00081   *
00082   * @return 1 if pressed, 0 if not.
00083   */
00084 int MicroBitMultiButton::isSubButtonPressed(uint16_t button)
00085 {
00086     if (button == button1)
00087         return status & MICROBIT_MULTI_BUTTON_STATE_1;
00088 
00089     if (button == button2)
00090         return status & MICROBIT_MULTI_BUTTON_STATE_2;
00091 
00092     return 0;
00093 }
00094 
00095 /**
00096   * Determines if the given button id is marked as held.
00097   *
00098   * @param button the id of the button whose state we would like to retrieve.
00099   *
00100   * @return 1 if held, 0 if not.
00101   */
00102 int MicroBitMultiButton::isSubButtonHeld(uint16_t button)
00103 {
00104     if (button == button1)
00105         return status & MICROBIT_MULTI_BUTTON_HOLD_TRIGGERED_1;
00106 
00107     if (button == button2)
00108         return status & MICROBIT_MULTI_BUTTON_HOLD_TRIGGERED_2;
00109 
00110     return 0;
00111 }
00112 
00113 /**
00114   * Determines if the given button id is marked as supressed.
00115   *
00116   * @param button the id of the button whose state we would like to retrieve.
00117   *
00118   * @return 1 if supressed, 0 if not.
00119   */
00120 int MicroBitMultiButton::isSubButtonSupressed(uint16_t button)
00121 {
00122     if (button == button1)
00123         return status & MICROBIT_MULTI_BUTTON_SUPRESSED_1;
00124 
00125     if (button == button2)
00126         return status & MICROBIT_MULTI_BUTTON_SUPRESSED_2;
00127 
00128     return 0;
00129 }
00130 
00131 /**
00132   * Configures the button pressed state for the given button id.
00133   *
00134   * @param button the id of the button whose state requires updating.
00135   *
00136   * @param value the value to set for this buttons state. (Transformed into a logical 0 or 1).
00137   */
00138 void MicroBitMultiButton::setButtonState(uint16_t button, int value)
00139 {
00140     if (button == button1)
00141     {
00142         if (value)
00143             status |= MICROBIT_MULTI_BUTTON_STATE_1;
00144         else
00145             status &= ~MICROBIT_MULTI_BUTTON_STATE_1;
00146     }
00147 
00148     if (button == button2)
00149     {
00150         if (value)
00151             status |= MICROBIT_MULTI_BUTTON_STATE_2;
00152         else
00153             status &= ~MICROBIT_MULTI_BUTTON_STATE_2;
00154     }
00155 }
00156 
00157 /**
00158   * Configures the button held state for the given button id.
00159   *
00160   * @param button the id of the button whose state requires updating.
00161   *
00162   * @param value the value to set for this buttons state. (Transformed into a logical 0 or 1).
00163   */
00164 void MicroBitMultiButton::setHoldState(uint16_t button, int value)
00165 {
00166     if (button == button1)
00167     {
00168         if (value)
00169             status |= MICROBIT_MULTI_BUTTON_HOLD_TRIGGERED_1;
00170         else
00171             status &= ~MICROBIT_MULTI_BUTTON_HOLD_TRIGGERED_1;
00172     }
00173 
00174     if (button == button2)
00175     {
00176         if (value)
00177             status |= MICROBIT_MULTI_BUTTON_HOLD_TRIGGERED_2;
00178         else
00179             status &= ~MICROBIT_MULTI_BUTTON_HOLD_TRIGGERED_2;
00180     }
00181 }
00182 
00183 /**
00184   * Configures the button suppressed state for the given button id.
00185   *
00186   * @param button the id of the button whose state requires updating.
00187   *
00188   * @param value the value to set for this buttons state. (Transformed into a logical 0 or 1).
00189   */
00190 void MicroBitMultiButton::setSupressedState(uint16_t button, int value)
00191 {
00192     if (button == button1)
00193     {
00194         if (value)
00195             status |= MICROBIT_MULTI_BUTTON_SUPRESSED_1;
00196         else
00197             status &= ~MICROBIT_MULTI_BUTTON_SUPRESSED_1;
00198     }
00199 
00200     if (button == button2)
00201     {
00202         if (value)
00203             status |= MICROBIT_MULTI_BUTTON_SUPRESSED_2;
00204         else
00205             status &= ~MICROBIT_MULTI_BUTTON_SUPRESSED_2;
00206     }
00207 }
00208 
00209 /**
00210   * Changes the event configuration of this button to the given MicroBitButtonEventConfiguration.
00211   * All subsequent events generated by this button will then be informed by this configuration.
00212   *
00213   * @param config The new configuration for this button. Legal values are MICROBIT_BUTTON_ALL_EVENTS or MICROBIT_BUTTON_SIMPLE_EVENTS.
00214   *
00215   * @code
00216   * // Configure a button to generate all possible events.
00217   * buttonAB.setEventConfiguration(MICROBIT_BUTTON_ALL_EVENTS);
00218   *
00219   * // Configure a button to suppress MICROBIT_BUTTON_EVT_CLICK and MICROBIT_BUTTON_EVT_LONG_CLICK events.
00220   * buttonAB.setEventConfiguration(MICROBIT_BUTTON_SIMPLE_EVENTS);
00221   * @endcode
00222   */
00223 void MicroBitMultiButton::setEventConfiguration(MicroBitButtonEventConfiguration config)
00224 {
00225     this->eventConfiguration = config;
00226 }
00227 
00228 /**
00229   * A member function that is invoked when any event is detected from the two
00230   * button IDs this MicrobitMultiButton instance was constructed with.
00231   *
00232   * @param evt the event received from the default EventModel.
00233   */
00234 void MicroBitMultiButton::onButtonEvent(MicroBitEvent evt)
00235 {
00236     int button = evt.source;
00237     int otherButton = otherSubButton(button);
00238 
00239     switch(evt.value)
00240     {
00241         case MICROBIT_BUTTON_EVT_DOWN:
00242             setButtonState(button, 1);
00243             if(isSubButtonPressed(otherButton))
00244                 MicroBitEvent e(id, MICROBIT_BUTTON_EVT_DOWN);
00245 
00246         break;
00247 
00248         case MICROBIT_BUTTON_EVT_HOLD:
00249             setHoldState(button, 1);
00250             if(isSubButtonHeld(otherButton))
00251                 MicroBitEvent e(id, MICROBIT_BUTTON_EVT_HOLD);
00252 
00253         break;
00254 
00255         case MICROBIT_BUTTON_EVT_UP:
00256             if(isSubButtonPressed(otherButton))
00257             {
00258                 MicroBitEvent e(id, MICROBIT_BUTTON_EVT_UP);
00259 
00260                 if (isSubButtonHeld(button) && isSubButtonHeld(otherButton))
00261                     MicroBitEvent e(id, MICROBIT_BUTTON_EVT_LONG_CLICK);
00262                 else
00263                     MicroBitEvent e(id, MICROBIT_BUTTON_EVT_CLICK);
00264 
00265                 setSupressedState(otherButton, 1);
00266             }
00267             else if (!isSubButtonSupressed(button) && eventConfiguration == MICROBIT_BUTTON_ALL_EVENTS)
00268             {
00269                 if (isSubButtonHeld(button))
00270                     MicroBitEvent e(button, MICROBIT_BUTTON_EVT_LONG_CLICK);
00271                 else
00272                     MicroBitEvent e(button, MICROBIT_BUTTON_EVT_CLICK);
00273             }
00274 
00275             setButtonState(button, 0);
00276             setHoldState(button, 0);
00277             setSupressedState(button, 0);
00278 
00279         break;
00280 
00281     }
00282 }
00283 
00284 
00285 /**
00286   * Tests if this MicroBitMultiButton instance is virtually pressed.
00287   *
00288   * @return 1 if both physical buttons are pressed simultaneously.
00289   *
00290   * @code
00291   * if(buttonAB.isPressed())
00292   *     display.scroll("Pressed!");
00293   * @endcode
00294   */
00295 int MicroBitMultiButton::isPressed()
00296 {
00297     return ((status & MICROBIT_MULTI_BUTTON_STATE_1) && (status & MICROBIT_MULTI_BUTTON_STATE_2));
00298 }