Solution for Bluetooth SIG hands-on training course
Dependencies: BLE_API mbed-dev-bin nRF51822-bluetooth-mdw
Fork of microbit-dal-bluetooth-mdw_starter by
source/drivers/MicroBitButton.cpp@22:23d7b9a4b082, 2016-07-13 (annotated)
- Committer:
- LancasterUniversity
- Date:
- Wed Jul 13 12:17:54 2016 +0100
- Revision:
- 22:23d7b9a4b082
- Parent:
- 1:8aa5cdb4ab67
Synchronized with git rev 7cf98c22
Author: James Devine
microbit-dal: patch for fiber_wake_on_event
fiber_wake_on_event used to crash after forking a FOB fiber.
It would attempt to obtain a new fiber context, and would place it on the wait queue.
Then when that fiber was paged in, the context of that fiber would not have been
initialised, as the function presumed schedule would be called immediately after
fiber initialisation.
This patch catches that edge case.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Jonathan Austin |
1:8aa5cdb4ab67 | 1 | /* |
Jonathan Austin |
1:8aa5cdb4ab67 | 2 | The MIT License (MIT) |
Jonathan Austin |
1:8aa5cdb4ab67 | 3 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 4 | Copyright (c) 2016 British Broadcasting Corporation. |
Jonathan Austin |
1:8aa5cdb4ab67 | 5 | This software is provided by Lancaster University by arrangement with the BBC. |
Jonathan Austin |
1:8aa5cdb4ab67 | 6 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 7 | Permission is hereby granted, free of charge, to any person obtaining a |
Jonathan Austin |
1:8aa5cdb4ab67 | 8 | copy of this software and associated documentation files (the "Software"), |
Jonathan Austin |
1:8aa5cdb4ab67 | 9 | to deal in the Software without restriction, including without limitation |
Jonathan Austin |
1:8aa5cdb4ab67 | 10 | the rights to use, copy, modify, merge, publish, distribute, sublicense, |
Jonathan Austin |
1:8aa5cdb4ab67 | 11 | and/or sell copies of the Software, and to permit persons to whom the |
Jonathan Austin |
1:8aa5cdb4ab67 | 12 | Software is furnished to do so, subject to the following conditions: |
Jonathan Austin |
1:8aa5cdb4ab67 | 13 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 14 | The above copyright notice and this permission notice shall be included in |
Jonathan Austin |
1:8aa5cdb4ab67 | 15 | all copies or substantial portions of the Software. |
Jonathan Austin |
1:8aa5cdb4ab67 | 16 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
Jonathan Austin |
1:8aa5cdb4ab67 | 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
Jonathan Austin |
1:8aa5cdb4ab67 | 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
Jonathan Austin |
1:8aa5cdb4ab67 | 20 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
Jonathan Austin |
1:8aa5cdb4ab67 | 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
Jonathan Austin |
1:8aa5cdb4ab67 | 22 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
Jonathan Austin |
1:8aa5cdb4ab67 | 23 | DEALINGS IN THE SOFTWARE. |
Jonathan Austin |
1:8aa5cdb4ab67 | 24 | */ |
Jonathan Austin |
1:8aa5cdb4ab67 | 25 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 26 | #include "MicroBitConfig.h" |
Jonathan Austin |
1:8aa5cdb4ab67 | 27 | #include "MicroBitButton.h" |
Jonathan Austin |
1:8aa5cdb4ab67 | 28 | #include "MicroBitSystemTimer.h" |
Jonathan Austin |
1:8aa5cdb4ab67 | 29 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 30 | /** |
Jonathan Austin |
1:8aa5cdb4ab67 | 31 | * Constructor. |
Jonathan Austin |
1:8aa5cdb4ab67 | 32 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 33 | * Create a software representation of a button. |
Jonathan Austin |
1:8aa5cdb4ab67 | 34 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 35 | * @param name the physical pin on the processor that should be used as input. |
Jonathan Austin |
1:8aa5cdb4ab67 | 36 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 37 | * @param id the ID of the new MicroBitButton object. |
Jonathan Austin |
1:8aa5cdb4ab67 | 38 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 39 | * @param eventConfiguration Configures the events that will be generated by this MicroBitButton instance. |
Jonathan Austin |
1:8aa5cdb4ab67 | 40 | * Defaults to MICROBIT_BUTTON_ALL_EVENTS. |
Jonathan Austin |
1:8aa5cdb4ab67 | 41 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 42 | * @param mode the configuration of internal pullups/pulldowns, as defined in the mbed PinMode class. PullNone by default. |
Jonathan Austin |
1:8aa5cdb4ab67 | 43 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 44 | * @code |
Jonathan Austin |
1:8aa5cdb4ab67 | 45 | * buttonA(MICROBIT_PIN_BUTTON_A, MICROBIT_ID_BUTTON_A); |
Jonathan Austin |
1:8aa5cdb4ab67 | 46 | * @endcode |
Jonathan Austin |
1:8aa5cdb4ab67 | 47 | */ |
Jonathan Austin |
1:8aa5cdb4ab67 | 48 | MicroBitButton::MicroBitButton(PinName name, uint16_t id, MicroBitButtonEventConfiguration eventConfiguration, PinMode mode) : pin(name, mode) |
Jonathan Austin |
1:8aa5cdb4ab67 | 49 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 50 | this->id = id; |
Jonathan Austin |
1:8aa5cdb4ab67 | 51 | this->name = name; |
Jonathan Austin |
1:8aa5cdb4ab67 | 52 | this->eventConfiguration = eventConfiguration; |
Jonathan Austin |
1:8aa5cdb4ab67 | 53 | this->downStartTime = 0; |
Jonathan Austin |
1:8aa5cdb4ab67 | 54 | this->sigma = 0; |
Jonathan Austin |
1:8aa5cdb4ab67 | 55 | system_timer_add_component(this); |
Jonathan Austin |
1:8aa5cdb4ab67 | 56 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 57 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 58 | /** |
Jonathan Austin |
1:8aa5cdb4ab67 | 59 | * Changes the event configuration used by this button to the given MicroBitButtonEventConfiguration. |
Jonathan Austin |
1:8aa5cdb4ab67 | 60 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 61 | * All subsequent events generated by this button will then be informed by this configuraiton. |
Jonathan Austin |
1:8aa5cdb4ab67 | 62 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 63 | * @param config The new configuration for this button. Legal values are MICROBIT_BUTTON_ALL_EVENTS or MICROBIT_BUTTON_SIMPLE_EVENTS. |
Jonathan Austin |
1:8aa5cdb4ab67 | 64 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 65 | * Example: |
Jonathan Austin |
1:8aa5cdb4ab67 | 66 | * @code |
Jonathan Austin |
1:8aa5cdb4ab67 | 67 | * // Configure a button to generate all possible events. |
Jonathan Austin |
1:8aa5cdb4ab67 | 68 | * buttonA.setEventConfiguration(MICROBIT_BUTTON_ALL_EVENTS); |
Jonathan Austin |
1:8aa5cdb4ab67 | 69 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 70 | * // Configure a button to suppress MICROBIT_BUTTON_EVT_CLICK and MICROBIT_BUTTON_EVT_LONG_CLICK events. |
Jonathan Austin |
1:8aa5cdb4ab67 | 71 | * buttonA.setEventConfiguration(MICROBIT_BUTTON_SIMPLE_EVENTS); |
Jonathan Austin |
1:8aa5cdb4ab67 | 72 | * @endcode |
Jonathan Austin |
1:8aa5cdb4ab67 | 73 | */ |
Jonathan Austin |
1:8aa5cdb4ab67 | 74 | void MicroBitButton::setEventConfiguration(MicroBitButtonEventConfiguration config) |
Jonathan Austin |
1:8aa5cdb4ab67 | 75 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 76 | this->eventConfiguration = config; |
Jonathan Austin |
1:8aa5cdb4ab67 | 77 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 78 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 79 | /** |
Jonathan Austin |
1:8aa5cdb4ab67 | 80 | * periodic callback from MicroBit system timer. |
Jonathan Austin |
1:8aa5cdb4ab67 | 81 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 82 | * Check for state change for this button, and fires various events on a state change. |
Jonathan Austin |
1:8aa5cdb4ab67 | 83 | */ |
Jonathan Austin |
1:8aa5cdb4ab67 | 84 | void MicroBitButton::systemTick() |
Jonathan Austin |
1:8aa5cdb4ab67 | 85 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 86 | // |
Jonathan Austin |
1:8aa5cdb4ab67 | 87 | // If the pin is pulled low (touched), increment our culumative counter. |
Jonathan Austin |
1:8aa5cdb4ab67 | 88 | // otherwise, decrement it. We're essentially building a lazy follower here. |
Jonathan Austin |
1:8aa5cdb4ab67 | 89 | // This makes the output debounced for buttons, and desensitizes touch sensors |
Jonathan Austin |
1:8aa5cdb4ab67 | 90 | // (particularly in environments where there is mains noise!) |
Jonathan Austin |
1:8aa5cdb4ab67 | 91 | // |
Jonathan Austin |
1:8aa5cdb4ab67 | 92 | if(!pin) |
Jonathan Austin |
1:8aa5cdb4ab67 | 93 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 94 | if (sigma < MICROBIT_BUTTON_SIGMA_MAX) |
Jonathan Austin |
1:8aa5cdb4ab67 | 95 | sigma++; |
Jonathan Austin |
1:8aa5cdb4ab67 | 96 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 97 | else |
Jonathan Austin |
1:8aa5cdb4ab67 | 98 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 99 | if (sigma > MICROBIT_BUTTON_SIGMA_MIN) |
Jonathan Austin |
1:8aa5cdb4ab67 | 100 | sigma--; |
Jonathan Austin |
1:8aa5cdb4ab67 | 101 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 102 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 103 | // Check to see if we have off->on state change. |
Jonathan Austin |
1:8aa5cdb4ab67 | 104 | if(sigma > MICROBIT_BUTTON_SIGMA_THRESH_HI && !(status & MICROBIT_BUTTON_STATE)) |
Jonathan Austin |
1:8aa5cdb4ab67 | 105 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 106 | // Record we have a state change, and raise an event. |
Jonathan Austin |
1:8aa5cdb4ab67 | 107 | status |= MICROBIT_BUTTON_STATE; |
Jonathan Austin |
1:8aa5cdb4ab67 | 108 | MicroBitEvent evt(id,MICROBIT_BUTTON_EVT_DOWN); |
Jonathan Austin |
1:8aa5cdb4ab67 | 109 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 110 | //Record the time the button was pressed. |
Jonathan Austin |
1:8aa5cdb4ab67 | 111 | downStartTime = system_timer_current_time(); |
Jonathan Austin |
1:8aa5cdb4ab67 | 112 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 113 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 114 | // Check to see if we have on->off state change. |
Jonathan Austin |
1:8aa5cdb4ab67 | 115 | if(sigma < MICROBIT_BUTTON_SIGMA_THRESH_LO && (status & MICROBIT_BUTTON_STATE)) |
Jonathan Austin |
1:8aa5cdb4ab67 | 116 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 117 | status = 0; |
Jonathan Austin |
1:8aa5cdb4ab67 | 118 | MicroBitEvent evt(id,MICROBIT_BUTTON_EVT_UP); |
Jonathan Austin |
1:8aa5cdb4ab67 | 119 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 120 | if (eventConfiguration == MICROBIT_BUTTON_ALL_EVENTS) |
Jonathan Austin |
1:8aa5cdb4ab67 | 121 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 122 | //determine if this is a long click or a normal click and send event |
Jonathan Austin |
1:8aa5cdb4ab67 | 123 | if((system_timer_current_time() - downStartTime) >= MICROBIT_BUTTON_LONG_CLICK_TIME) |
Jonathan Austin |
1:8aa5cdb4ab67 | 124 | MicroBitEvent evt(id,MICROBIT_BUTTON_EVT_LONG_CLICK); |
Jonathan Austin |
1:8aa5cdb4ab67 | 125 | else |
Jonathan Austin |
1:8aa5cdb4ab67 | 126 | MicroBitEvent evt(id,MICROBIT_BUTTON_EVT_CLICK); |
Jonathan Austin |
1:8aa5cdb4ab67 | 127 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 128 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 129 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 130 | //if button is pressed and the hold triggered event state is not triggered AND we are greater than the button debounce value |
Jonathan Austin |
1:8aa5cdb4ab67 | 131 | if((status & MICROBIT_BUTTON_STATE) && !(status & MICROBIT_BUTTON_STATE_HOLD_TRIGGERED) && (system_timer_current_time() - downStartTime) >= MICROBIT_BUTTON_HOLD_TIME) |
Jonathan Austin |
1:8aa5cdb4ab67 | 132 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 133 | //set the hold triggered event flag |
Jonathan Austin |
1:8aa5cdb4ab67 | 134 | status |= MICROBIT_BUTTON_STATE_HOLD_TRIGGERED; |
Jonathan Austin |
1:8aa5cdb4ab67 | 135 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 136 | //fire hold event |
Jonathan Austin |
1:8aa5cdb4ab67 | 137 | MicroBitEvent evt(id,MICROBIT_BUTTON_EVT_HOLD); |
Jonathan Austin |
1:8aa5cdb4ab67 | 138 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 139 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 140 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 141 | /** |
Jonathan Austin |
1:8aa5cdb4ab67 | 142 | * Tests if this Button is currently pressed. |
Jonathan Austin |
1:8aa5cdb4ab67 | 143 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 144 | * @code |
Jonathan Austin |
1:8aa5cdb4ab67 | 145 | * if(buttonA.isPressed()) |
Jonathan Austin |
1:8aa5cdb4ab67 | 146 | * display.scroll("Pressed!"); |
Jonathan Austin |
1:8aa5cdb4ab67 | 147 | * @endcode |
Jonathan Austin |
1:8aa5cdb4ab67 | 148 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 149 | * @return 1 if this button is pressed, 0 otherwise. |
Jonathan Austin |
1:8aa5cdb4ab67 | 150 | */ |
Jonathan Austin |
1:8aa5cdb4ab67 | 151 | int MicroBitButton::isPressed() |
Jonathan Austin |
1:8aa5cdb4ab67 | 152 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 153 | return status & MICROBIT_BUTTON_STATE ? 1 : 0; |
Jonathan Austin |
1:8aa5cdb4ab67 | 154 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 155 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 156 | /** |
Jonathan Austin |
1:8aa5cdb4ab67 | 157 | * Destructor for MicroBitButton, where we deregister this instance from the array of fiber components. |
Jonathan Austin |
1:8aa5cdb4ab67 | 158 | */ |
Jonathan Austin |
1:8aa5cdb4ab67 | 159 | MicroBitButton::~MicroBitButton() |
Jonathan Austin |
1:8aa5cdb4ab67 | 160 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 161 | system_timer_remove_component(this); |
Jonathan Austin |
1:8aa5cdb4ab67 | 162 | } |