mbed.org local branch of microbit-dal. The real version lives in git at https://github.com/lancaster-university/microbit-dal

Dependencies:   BLE_API nRF51822 mbed-dev-bin

Dependents:   microbit Microbit IoTChallenge1 microbit ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MicroBitButton.cpp Source File

MicroBitButton.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 #include "MicroBitConfig.h"
00027 #include "MicroBitButton.h"
00028 #include "MicroBitSystemTimer.h"
00029 
00030 /**
00031   * Constructor.
00032   *
00033   * Create a software representation of a button.
00034   *
00035   * @param name the physical pin on the processor that should be used as input.
00036   *
00037   * @param id the ID of the new MicroBitButton object.
00038   *
00039   * @param eventConfiguration Configures the events that will be generated by this MicroBitButton instance.
00040   *                           Defaults to MICROBIT_BUTTON_ALL_EVENTS.
00041   *
00042   * @param mode the configuration of internal pullups/pulldowns, as defined in the mbed PinMode class. PullNone by default.
00043   *
00044   * @code
00045   * buttonA(MICROBIT_PIN_BUTTON_A, MICROBIT_ID_BUTTON_A);
00046   * @endcode
00047   */
00048 MicroBitButton::MicroBitButton(PinName name, uint16_t id, MicroBitButtonEventConfiguration eventConfiguration, PinMode mode) : pin(name, mode)
00049 {
00050     this->id = id;
00051     this->name = name;
00052     this->eventConfiguration = eventConfiguration;
00053     this->downStartTime = 0;
00054     this->sigma = 0;
00055     system_timer_add_component(this);
00056 }
00057 
00058 /**
00059   * Changes the event configuration used by this button to the given MicroBitButtonEventConfiguration.
00060   *
00061   * All subsequent events generated by this button will then be informed by this configuraiton.
00062   *
00063   * @param config The new configuration for this button. Legal values are MICROBIT_BUTTON_ALL_EVENTS or MICROBIT_BUTTON_SIMPLE_EVENTS.
00064   *
00065   * Example:
00066   * @code
00067   * // Configure a button to generate all possible events.
00068   * buttonA.setEventConfiguration(MICROBIT_BUTTON_ALL_EVENTS);
00069   *
00070   * // Configure a button to suppress MICROBIT_BUTTON_EVT_CLICK and MICROBIT_BUTTON_EVT_LONG_CLICK events.
00071   * buttonA.setEventConfiguration(MICROBIT_BUTTON_SIMPLE_EVENTS);
00072   * @endcode
00073   */
00074 void MicroBitButton::setEventConfiguration(MicroBitButtonEventConfiguration config)
00075 {
00076     this->eventConfiguration = config;
00077 }
00078 
00079 /**
00080   * periodic callback from MicroBit system timer.
00081   *
00082   * Check for state change for this button, and fires various events on a state change.
00083   */
00084 void MicroBitButton::systemTick()
00085 {
00086     //
00087     // If the pin is pulled low (touched), increment our culumative counter.
00088     // otherwise, decrement it. We're essentially building a lazy follower here.
00089     // This makes the output debounced for buttons, and desensitizes touch sensors
00090     // (particularly in environments where there is mains noise!)
00091     //
00092     if(!pin)
00093     {
00094         if (sigma < MICROBIT_BUTTON_SIGMA_MAX)
00095             sigma++;
00096     }
00097     else
00098     {
00099         if (sigma > MICROBIT_BUTTON_SIGMA_MIN)
00100             sigma--;
00101     }
00102 
00103     // Check to see if we have off->on state change.
00104     if(sigma > MICROBIT_BUTTON_SIGMA_THRESH_HI && !(status & MICROBIT_BUTTON_STATE))
00105     {
00106         // Record we have a state change, and raise an event.
00107         status |= MICROBIT_BUTTON_STATE;
00108         MicroBitEvent evt(id,MICROBIT_BUTTON_EVT_DOWN);
00109 
00110         //Record the time the button was pressed.
00111         downStartTime = system_timer_current_time();
00112     }
00113 
00114     // Check to see if we have on->off state change.
00115     if(sigma < MICROBIT_BUTTON_SIGMA_THRESH_LO && (status & MICROBIT_BUTTON_STATE))
00116     {
00117         status = 0;
00118         MicroBitEvent evt(id,MICROBIT_BUTTON_EVT_UP);
00119 
00120        if (eventConfiguration == MICROBIT_BUTTON_ALL_EVENTS)
00121        {
00122            //determine if this is a long click or a normal click and send event
00123            if((system_timer_current_time() - downStartTime) >= MICROBIT_BUTTON_LONG_CLICK_TIME)
00124                MicroBitEvent evt(id,MICROBIT_BUTTON_EVT_LONG_CLICK);
00125            else
00126                MicroBitEvent evt(id,MICROBIT_BUTTON_EVT_CLICK);
00127        }
00128     }
00129 
00130     //if button is pressed and the hold triggered event state is not triggered AND we are greater than the button debounce value
00131     if((status & MICROBIT_BUTTON_STATE) && !(status & MICROBIT_BUTTON_STATE_HOLD_TRIGGERED) && (system_timer_current_time() - downStartTime) >= MICROBIT_BUTTON_HOLD_TIME)
00132     {
00133         //set the hold triggered event flag
00134         status |= MICROBIT_BUTTON_STATE_HOLD_TRIGGERED;
00135 
00136         //fire hold event
00137         MicroBitEvent evt(id,MICROBIT_BUTTON_EVT_HOLD);
00138     }
00139 }
00140 
00141 /**
00142   * Tests if this Button is currently pressed.
00143   *
00144   * @code
00145   * if(buttonA.isPressed())
00146   *     display.scroll("Pressed!");
00147   * @endcode
00148   *
00149   * @return 1 if this button is pressed, 0 otherwise.
00150   */
00151 int MicroBitButton::isPressed()
00152 {
00153     return status & MICROBIT_BUTTON_STATE ? 1 : 0;
00154 }
00155 
00156 /**
00157   * Destructor for MicroBitButton, where we deregister this instance from the array of fiber components.
00158   */
00159 MicroBitButton::~MicroBitButton()
00160 {
00161     system_timer_remove_component(this);
00162 }