Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of microbit by
source/MicroBit.cpp@8:3a7fdc92403c, 2016-06-01 (annotated)
- Committer:
- cefn
- Date:
- Wed Jun 01 17:44:05 2016 +0000
- Revision:
- 8:3a7fdc92403c
- Parent:
- 5:8052323b72d2
Attempting to publish a tree
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Jonathan Austin |
1:af427e419320 | 1 | /* |
Jonathan Austin |
1:af427e419320 | 2 | The MIT License (MIT) |
Jonathan Austin |
1:af427e419320 | 3 | |
Jonathan Austin |
1:af427e419320 | 4 | Copyright (c) 2016 British Broadcasting Corporation. |
Jonathan Austin |
1:af427e419320 | 5 | This software is provided by Lancaster University by arrangement with the BBC. |
Jonathan Austin |
1:af427e419320 | 6 | |
Jonathan Austin |
1:af427e419320 | 7 | Permission is hereby granted, free of charge, to any person obtaining a |
Jonathan Austin |
1:af427e419320 | 8 | copy of this software and associated documentation files (the "Software"), |
Jonathan Austin |
1:af427e419320 | 9 | to deal in the Software without restriction, including without limitation |
Jonathan Austin |
1:af427e419320 | 10 | the rights to use, copy, modify, merge, publish, distribute, sublicense, |
Jonathan Austin |
1:af427e419320 | 11 | and/or sell copies of the Software, and to permit persons to whom the |
Jonathan Austin |
1:af427e419320 | 12 | Software is furnished to do so, subject to the following conditions: |
Jonathan Austin |
1:af427e419320 | 13 | |
Jonathan Austin |
1:af427e419320 | 14 | The above copyright notice and this permission notice shall be included in |
Jonathan Austin |
1:af427e419320 | 15 | all copies or substantial portions of the Software. |
Jonathan Austin |
1:af427e419320 | 16 | |
Jonathan Austin |
1:af427e419320 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
Jonathan Austin |
1:af427e419320 | 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
Jonathan Austin |
1:af427e419320 | 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
Jonathan Austin |
1:af427e419320 | 20 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
Jonathan Austin |
1:af427e419320 | 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
Jonathan Austin |
1:af427e419320 | 22 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
Jonathan Austin |
1:af427e419320 | 23 | DEALINGS IN THE SOFTWARE. |
Jonathan Austin |
1:af427e419320 | 24 | */ |
Jonathan Austin |
1:af427e419320 | 25 | |
Jonathan Austin |
1:af427e419320 | 26 | #include "MicroBitConfig.h" |
Jonathan Austin |
1:af427e419320 | 27 | /* |
Jonathan Austin |
1:af427e419320 | 28 | * The underlying Nordic libraries that support BLE do not compile cleanly with the stringent GCC settings we employ |
Jonathan Austin |
1:af427e419320 | 29 | * If we're compiling under GCC, then we suppress any warnings generated from this code (but not the rest of the DAL) |
Jonathan Austin |
1:af427e419320 | 30 | * The ARM cc compiler is more tolerant. We don't test __GNUC__ here to detect GCC as ARMCC also typically sets this |
Jonathan Austin |
1:af427e419320 | 31 | * as a compatability option, but does not support the options used... |
Jonathan Austin |
1:af427e419320 | 32 | */ |
Jonathan Austin |
1:af427e419320 | 33 | #if !defined(__arm) |
Jonathan Austin |
1:af427e419320 | 34 | #pragma GCC diagnostic ignored "-Wunused-function" |
Jonathan Austin |
1:af427e419320 | 35 | #pragma GCC diagnostic push |
Jonathan Austin |
1:af427e419320 | 36 | #pragma GCC diagnostic ignored "-Wunused-parameter" |
Jonathan Austin |
1:af427e419320 | 37 | #endif |
Jonathan Austin |
1:af427e419320 | 38 | |
Jonathan Austin |
1:af427e419320 | 39 | #include "MicroBit.h" |
Jonathan Austin |
1:af427e419320 | 40 | |
Jonathan Austin |
1:af427e419320 | 41 | #include "nrf_soc.h" |
Jonathan Austin |
1:af427e419320 | 42 | |
Jonathan Austin |
1:af427e419320 | 43 | /* |
Jonathan Austin |
1:af427e419320 | 44 | * Return to our predefined compiler settings. |
Jonathan Austin |
1:af427e419320 | 45 | */ |
Jonathan Austin |
1:af427e419320 | 46 | #if !defined(__arm) |
Jonathan Austin |
1:af427e419320 | 47 | #pragma GCC diagnostic pop |
Jonathan Austin |
1:af427e419320 | 48 | #endif |
Jonathan Austin |
1:af427e419320 | 49 | |
Jonathan Austin |
1:af427e419320 | 50 | #if CONFIG_ENABLED(MICROBIT_DBG) |
Jonathan Austin |
1:af427e419320 | 51 | // We create and initialize to NULL here, but MicroBitSerial will automatically update this as needed in its constructor. |
Jonathan Austin |
1:af427e419320 | 52 | RawSerial* SERIAL_DEBUG = NULL; |
Jonathan Austin |
1:af427e419320 | 53 | #endif |
Jonathan Austin |
1:af427e419320 | 54 | |
Jonathan Austin |
1:af427e419320 | 55 | /** |
Jonathan Austin |
1:af427e419320 | 56 | * Constructor. |
Jonathan Austin |
1:af427e419320 | 57 | * |
Jonathan Austin |
1:af427e419320 | 58 | * Create a representation of a MicroBit device, which includes member variables |
Jonathan Austin |
1:af427e419320 | 59 | * that represent various device drivers used to control aspects of the micro:bit. |
Jonathan Austin |
1:af427e419320 | 60 | */ |
Jonathan Austin |
1:af427e419320 | 61 | MicroBit::MicroBit() : |
Jonathan Austin |
1:af427e419320 | 62 | serial(USBTX, USBRX), |
Jonathan Austin |
1:af427e419320 | 63 | resetButton(MICROBIT_PIN_BUTTON_RESET), |
Jonathan Austin |
1:af427e419320 | 64 | storage(), |
Jonathan Austin |
1:af427e419320 | 65 | i2c(I2C_SDA0, I2C_SCL0), |
Jonathan Austin |
1:af427e419320 | 66 | messageBus(), |
Jonathan Austin |
1:af427e419320 | 67 | display(), |
Jonathan Austin |
1:af427e419320 | 68 | buttonA(MICROBIT_PIN_BUTTON_A, MICROBIT_ID_BUTTON_A), |
Jonathan Austin |
1:af427e419320 | 69 | buttonB(MICROBIT_PIN_BUTTON_B, MICROBIT_ID_BUTTON_B), |
Jonathan Austin |
1:af427e419320 | 70 | buttonAB(MICROBIT_ID_BUTTON_A,MICROBIT_ID_BUTTON_B, MICROBIT_ID_BUTTON_AB), |
Jonathan Austin |
1:af427e419320 | 71 | accelerometer(i2c), |
Jonathan Austin |
1:af427e419320 | 72 | compass(i2c, accelerometer, storage), |
Jonathan Austin |
1:af427e419320 | 73 | compassCalibrator(compass, accelerometer, display), |
Jonathan Austin |
1:af427e419320 | 74 | thermometer(storage), |
Jonathan Austin |
1:af427e419320 | 75 | io(MICROBIT_ID_IO_P0,MICROBIT_ID_IO_P1,MICROBIT_ID_IO_P2, |
Jonathan Austin |
1:af427e419320 | 76 | MICROBIT_ID_IO_P3,MICROBIT_ID_IO_P4,MICROBIT_ID_IO_P5, |
Jonathan Austin |
1:af427e419320 | 77 | MICROBIT_ID_IO_P6,MICROBIT_ID_IO_P7,MICROBIT_ID_IO_P8, |
Jonathan Austin |
1:af427e419320 | 78 | MICROBIT_ID_IO_P9,MICROBIT_ID_IO_P10,MICROBIT_ID_IO_P11, |
Jonathan Austin |
1:af427e419320 | 79 | MICROBIT_ID_IO_P12,MICROBIT_ID_IO_P13,MICROBIT_ID_IO_P14, |
Jonathan Austin |
1:af427e419320 | 80 | MICROBIT_ID_IO_P15,MICROBIT_ID_IO_P16,MICROBIT_ID_IO_P19, |
Jonathan Austin |
1:af427e419320 | 81 | MICROBIT_ID_IO_P20), |
Jonathan Austin |
1:af427e419320 | 82 | bleManager(storage), |
Jonathan Austin |
1:af427e419320 | 83 | radio(), |
Jonathan Austin |
1:af427e419320 | 84 | ble(NULL) |
Jonathan Austin |
1:af427e419320 | 85 | { |
Jonathan Austin |
1:af427e419320 | 86 | // Clear our status |
Jonathan Austin |
1:af427e419320 | 87 | status = 0; |
Jonathan Austin |
1:af427e419320 | 88 | |
Jonathan Austin |
1:af427e419320 | 89 | // Bring up soft reset functionality as soon as possible. |
Jonathan Austin |
1:af427e419320 | 90 | resetButton.mode(PullUp); |
Jonathan Austin |
1:af427e419320 | 91 | resetButton.fall(this, &MicroBit::reset); |
Jonathan Austin |
1:af427e419320 | 92 | } |
Jonathan Austin |
1:af427e419320 | 93 | |
Jonathan Austin |
1:af427e419320 | 94 | /** |
Jonathan Austin |
1:af427e419320 | 95 | * Post constructor initialisation method. |
Jonathan Austin |
1:af427e419320 | 96 | * |
Jonathan Austin |
1:af427e419320 | 97 | * This call will initialised the scheduler, memory allocator and Bluetooth stack. |
Jonathan Austin |
1:af427e419320 | 98 | * |
Jonathan Austin |
1:af427e419320 | 99 | * This is required as the Bluetooth stack can't be brought up in a |
Jonathan Austin |
1:af427e419320 | 100 | * static context i.e. in a constructor. |
Jonathan Austin |
1:af427e419320 | 101 | * |
Jonathan Austin |
1:af427e419320 | 102 | * @code |
Jonathan Austin |
1:af427e419320 | 103 | * uBit.init(); |
Jonathan Austin |
1:af427e419320 | 104 | * @endcode |
Jonathan Austin |
1:af427e419320 | 105 | * |
Jonathan Austin |
1:af427e419320 | 106 | * @note This method must be called before user code utilises any functionality |
Jonathan Austin |
1:af427e419320 | 107 | * contained by uBit. |
Jonathan Austin |
1:af427e419320 | 108 | */ |
Jonathan Austin |
1:af427e419320 | 109 | void MicroBit::init() |
Jonathan Austin |
1:af427e419320 | 110 | { |
Jonathan Austin |
1:af427e419320 | 111 | if (status & MICROBIT_INITIALIZED) |
Jonathan Austin |
1:af427e419320 | 112 | return; |
Jonathan Austin |
1:af427e419320 | 113 | |
Jonathan Austin |
1:af427e419320 | 114 | #if CONFIG_ENABLED(MICROBIT_HEAP_ALLOCATOR) |
Jonathan Austin |
1:af427e419320 | 115 | // Bring up a nested heap allocator. |
Jonathan Austin |
1:af427e419320 | 116 | microbit_create_nested_heap(MICROBIT_NESTED_HEAP_SIZE); |
Jonathan Austin |
1:af427e419320 | 117 | #endif |
Jonathan Austin |
1:af427e419320 | 118 | |
Jonathan Austin |
1:af427e419320 | 119 | // Bring up fiber scheduler. |
Jonathan Austin |
1:af427e419320 | 120 | scheduler_init(messageBus); |
Jonathan Austin |
1:af427e419320 | 121 | |
Jonathan Austin |
1:af427e419320 | 122 | // Seed our random number generator |
Jonathan Austin |
1:af427e419320 | 123 | seedRandom(); |
Jonathan Austin |
1:af427e419320 | 124 | |
Jonathan Austin |
1:af427e419320 | 125 | // Create an event handler to trap any handlers being created for I2C services. |
Jonathan Austin |
1:af427e419320 | 126 | // We do this to enable initialisation of those services only when they're used, |
Jonathan Austin |
1:af427e419320 | 127 | // which saves processor time, memeory and battery life. |
Jonathan Austin |
1:af427e419320 | 128 | messageBus.listen(MICROBIT_ID_MESSAGE_BUS_LISTENER, MICROBIT_EVT_ANY, this, &MicroBit::onListenerRegisteredEvent); |
Jonathan Austin |
1:af427e419320 | 129 | |
Jonathan Austin |
1:af427e419320 | 130 | status |= MICROBIT_INITIALIZED; |
Jonathan Austin |
1:af427e419320 | 131 | |
Jonathan Austin |
1:af427e419320 | 132 | #if CONFIG_ENABLED(MICROBIT_BLE_PAIRING_MODE) |
Jonathan Austin |
1:af427e419320 | 133 | // Test if we need to enter BLE pairing mode... |
Jonathan Austin |
1:af427e419320 | 134 | int i=0; |
Jonathan Austin |
1:af427e419320 | 135 | sleep(100); |
Jonathan Austin |
1:af427e419320 | 136 | while (buttonA.isPressed() && buttonB.isPressed() && i<10) |
Jonathan Austin |
1:af427e419320 | 137 | { |
Jonathan Austin |
1:af427e419320 | 138 | sleep(100); |
Jonathan Austin |
1:af427e419320 | 139 | i++; |
Jonathan Austin |
1:af427e419320 | 140 | |
Jonathan Austin |
1:af427e419320 | 141 | if (i == 10) |
Jonathan Austin |
1:af427e419320 | 142 | { |
Jonathan Austin |
1:af427e419320 | 143 | #if CONFIG_ENABLED(MICROBIT_HEAP_ALLOCATOR) && CONFIG_ENABLED(MICROBIT_HEAP_REUSE_SD) |
Jonathan Austin |
1:af427e419320 | 144 | microbit_create_heap(MICROBIT_SD_GATT_TABLE_START + MICROBIT_SD_GATT_TABLE_SIZE, MICROBIT_SD_LIMIT); |
Jonathan Austin |
1:af427e419320 | 145 | #endif |
Jonathan Austin |
1:af427e419320 | 146 | // Start the BLE stack, if it isn't already running. |
Jonathan Austin |
1:af427e419320 | 147 | if (!ble) |
Jonathan Austin |
1:af427e419320 | 148 | { |
Jonathan Austin |
1:af427e419320 | 149 | bleManager.init(getName(), getSerial(), messageBus, true); |
Jonathan Austin |
1:af427e419320 | 150 | ble = bleManager.ble; |
Jonathan Austin |
1:af427e419320 | 151 | } |
Jonathan Austin |
1:af427e419320 | 152 | |
Jonathan Austin |
1:af427e419320 | 153 | // Enter pairing mode, using the LED matrix for any necessary pairing operations |
Jonathan Austin |
1:af427e419320 | 154 | bleManager.pairingMode(display, buttonA); |
Jonathan Austin |
1:af427e419320 | 155 | } |
Jonathan Austin |
1:af427e419320 | 156 | } |
Jonathan Austin |
1:af427e419320 | 157 | #endif |
Jonathan Austin |
1:af427e419320 | 158 | |
Jonathan Austin |
1:af427e419320 | 159 | // Attempt to bring up a second heap region, using unused memory normally reserved for Soft Device. |
Jonathan Austin |
1:af427e419320 | 160 | #if CONFIG_ENABLED(MICROBIT_HEAP_ALLOCATOR) && CONFIG_ENABLED(MICROBIT_HEAP_REUSE_SD) |
Jonathan Austin |
1:af427e419320 | 161 | #if CONFIG_ENABLED(MICROBIT_BLE_ENABLED) |
Jonathan Austin |
1:af427e419320 | 162 | microbit_create_heap(MICROBIT_SD_GATT_TABLE_START + MICROBIT_SD_GATT_TABLE_SIZE, MICROBIT_SD_LIMIT); |
Jonathan Austin |
1:af427e419320 | 163 | #else |
Jonathan Austin |
1:af427e419320 | 164 | microbit_create_heap(MICROBIT_SRAM_BASE, MICROBIT_SD_LIMIT); |
Jonathan Austin |
1:af427e419320 | 165 | #endif |
Jonathan Austin |
1:af427e419320 | 166 | #endif |
Jonathan Austin |
1:af427e419320 | 167 | |
Jonathan Austin |
1:af427e419320 | 168 | #if CONFIG_ENABLED(MICROBIT_BLE_ENABLED) |
Jonathan Austin |
1:af427e419320 | 169 | // Start the BLE stack, if it isn't already running. |
Jonathan Austin |
1:af427e419320 | 170 | if (!ble) |
Jonathan Austin |
1:af427e419320 | 171 | { |
Jonathan Austin |
1:af427e419320 | 172 | bleManager.init(getName(), getSerial(), messageBus, false); |
Jonathan Austin |
1:af427e419320 | 173 | ble = bleManager.ble; |
Jonathan Austin |
1:af427e419320 | 174 | } |
Jonathan Austin |
1:af427e419320 | 175 | #endif |
Jonathan Austin |
1:af427e419320 | 176 | } |
Jonathan Austin |
1:af427e419320 | 177 | |
Jonathan Austin |
1:af427e419320 | 178 | /** |
Jonathan Austin |
1:af427e419320 | 179 | * A listener to perform actions as a result of Message Bus reflection. |
Jonathan Austin |
1:af427e419320 | 180 | * |
Jonathan Austin |
1:af427e419320 | 181 | * In some cases we want to perform lazy instantiation of components, such as |
Jonathan Austin |
1:af427e419320 | 182 | * the compass and the accelerometer, where we only want to add them to the idle |
Jonathan Austin |
1:af427e419320 | 183 | * fiber when someone has the intention of using these components. |
Jonathan Austin |
1:af427e419320 | 184 | */ |
Jonathan Austin |
1:af427e419320 | 185 | void MicroBit::onListenerRegisteredEvent(MicroBitEvent evt) |
Jonathan Austin |
1:af427e419320 | 186 | { |
Jonathan Austin |
1:af427e419320 | 187 | switch(evt.value) |
Jonathan Austin |
1:af427e419320 | 188 | { |
Jonathan Austin |
1:af427e419320 | 189 | case MICROBIT_ID_BUTTON_AB: |
Jonathan Austin |
1:af427e419320 | 190 | // A user has registered to receive events from the buttonAB multibutton. |
Jonathan Austin |
1:af427e419320 | 191 | // Disable click events from being generated by ButtonA and ButtonB, and defer the |
Jonathan Austin |
1:af427e419320 | 192 | // control of this to the multibutton handler. |
Jonathan Austin |
1:af427e419320 | 193 | // |
Jonathan Austin |
1:af427e419320 | 194 | // This way, buttons look independent unless a buttonAB is requested, at which |
Jonathan Austin |
1:af427e419320 | 195 | // point button A+B clicks can be correclty handled without breaking |
Jonathan Austin |
1:af427e419320 | 196 | // causal ordering. |
Jonathan Austin |
1:af427e419320 | 197 | buttonA.setEventConfiguration(MICROBIT_BUTTON_SIMPLE_EVENTS); |
Jonathan Austin |
1:af427e419320 | 198 | buttonB.setEventConfiguration(MICROBIT_BUTTON_SIMPLE_EVENTS); |
Jonathan Austin |
1:af427e419320 | 199 | buttonAB.setEventConfiguration(MICROBIT_BUTTON_ALL_EVENTS); |
Jonathan Austin |
1:af427e419320 | 200 | break; |
Jonathan Austin |
1:af427e419320 | 201 | |
Jonathan Austin |
1:af427e419320 | 202 | case MICROBIT_ID_COMPASS: |
Jonathan Austin |
1:af427e419320 | 203 | // A listener has been registered for the compass. |
Jonathan Austin |
1:af427e419320 | 204 | // The compass uses lazy instantiation, we just need to read the data once to start it running. |
Jonathan Austin |
1:af427e419320 | 205 | // Touch the compass through the heading() function to ensure it is calibrated. if it isn't this will launch any associated calibration algorithms. |
Jonathan Austin |
1:af427e419320 | 206 | compass.heading(); |
Jonathan Austin |
1:af427e419320 | 207 | |
Jonathan Austin |
1:af427e419320 | 208 | break; |
Jonathan Austin |
1:af427e419320 | 209 | |
Jonathan Austin |
1:af427e419320 | 210 | case MICROBIT_ID_ACCELEROMETER: |
LancasterUniversity | 5:8052323b72d2 | 211 | case MICROBIT_ID_GESTURE: |
Jonathan Austin |
1:af427e419320 | 212 | // A listener has been registered for the accelerometer. |
Jonathan Austin |
1:af427e419320 | 213 | // The accelerometer uses lazy instantiation, we just need to read the data once to start it running. |
Jonathan Austin |
1:af427e419320 | 214 | accelerometer.updateSample(); |
Jonathan Austin |
1:af427e419320 | 215 | break; |
Jonathan Austin |
1:af427e419320 | 216 | |
Jonathan Austin |
1:af427e419320 | 217 | case MICROBIT_ID_THERMOMETER: |
Jonathan Austin |
1:af427e419320 | 218 | // A listener has been registered for the thermometer. |
Jonathan Austin |
1:af427e419320 | 219 | // The thermometer uses lazy instantiation, we just need to read the data once to start it running. |
Jonathan Austin |
1:af427e419320 | 220 | thermometer.updateSample(); |
Jonathan Austin |
1:af427e419320 | 221 | break; |
Jonathan Austin |
1:af427e419320 | 222 | } |
LancasterUniversity | 5:8052323b72d2 | 223 | } |