developer.mbed.org branch of Lancaster University's microbit library. The real home for this is https://github.com/lancaster-university/microbit
Dependents: radio_receiver_test
Fork of microbit by
MicroBit.h
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 #ifndef MICROBIT_H 00027 #define MICROBIT_H 00028 00029 #include "mbed.h" 00030 00031 #include "MicroBitConfig.h" 00032 #include "MicroBitHeapAllocator.h" 00033 #include "MicroBitDevice.h" 00034 #include "ErrorNo.h" 00035 #include "MicroBitSystemTimer.h" 00036 #include "Matrix4.h" 00037 #include "MicroBitCompat.h" 00038 #include "MicroBitComponent.h" 00039 #include "ManagedType.h" 00040 #include "ManagedString.h" 00041 #include "MicroBitImage.h" 00042 #include "MicroBitFont.h" 00043 #include "MicroBitEvent.h" 00044 #include "DynamicPwm.h" 00045 #include "MicroBitI2C.h" 00046 #include "NotifyEvents.h" 00047 00048 #include "MicroBitButton.h" 00049 #include "MicroBitPin.h" 00050 #include "MicroBitCompass.h" 00051 #include "MicroBitCompassCalibrator.h" 00052 #include "MicroBitAccelerometer.h" 00053 #include "MicroBitThermometer.h" 00054 #include "MicroBitLightSensor.h" 00055 #include "MicroBitMultiButton.h" 00056 00057 #include "MicroBitSerial.h" 00058 #include "MicroBitIO.h" 00059 #include "MicroBitMatrixMaps.h" 00060 #include "MicroBitDisplay.h" 00061 00062 #include "MicroBitFiber.h" 00063 #include "MicroBitMessageBus.h" 00064 00065 #include "MicroBitBLEManager.h" 00066 #include "MicroBitRadio.h" 00067 #include "MicroBitStorage.h" 00068 00069 // MicroBit::flags values 00070 #define MICROBIT_INITIALIZED 0x01 00071 // Disable BLE for Radio test 00072 #define MICROBIT_BLE_ENABLED 0 00073 00074 /** 00075 * Class definition for a MicroBit device. 00076 * 00077 * Represents the device as a whole, and includes member variables that represent various device drivers 00078 * used to control aspects of the micro:bit. 00079 */ 00080 class MicroBit 00081 { 00082 private: 00083 00084 /** 00085 * A listener to perform actions as a result of Message Bus reflection. 00086 * 00087 * In some cases we want to perform lazy instantiation of components, such as 00088 * the compass and the accelerometer, where we only want to add them to the idle 00089 * fiber when someone has the intention of using these components. 00090 */ 00091 void onListenerRegisteredEvent(MicroBitEvent evt); 00092 00093 uint8_t status; 00094 00095 public: 00096 00097 // Serial Interface 00098 MicroBitSerial serial; 00099 00100 // Reset Button 00101 InterruptIn resetButton; 00102 00103 // Persistent key value store 00104 MicroBitStorage storage; 00105 00106 // I2C Interface 00107 MicroBitI2C i2c; 00108 00109 // Device level Message Bus abstraction 00110 MicroBitMessageBus messageBus; 00111 00112 // Member variables to represent each of the core components on the device. 00113 MicroBitDisplay display; 00114 MicroBitButton buttonA; 00115 MicroBitButton buttonB; 00116 MicroBitMultiButton buttonAB; 00117 MicroBitAccelerometer accelerometer; 00118 MicroBitCompass compass; 00119 MicroBitCompassCalibrator compassCalibrator; 00120 MicroBitThermometer thermometer; 00121 00122 //An object of available IO pins on the device 00123 MicroBitIO io; 00124 00125 // Bluetooth related member variables. 00126 MicroBitBLEManager bleManager; 00127 MicroBitRadio radio; 00128 BLEDevice *ble; 00129 00130 /** 00131 * Constructor. 00132 * 00133 * Create a representation of a MicroBit device, which includes member variables 00134 * that represent various device drivers used to control aspects of the micro:bit. 00135 */ 00136 MicroBit(); 00137 00138 /** 00139 * Post constructor initialisation method. 00140 * 00141 * This call will initialised the scheduler, memory allocator and Bluetooth stack. 00142 * 00143 * This is required as the Bluetooth stack can't be brought up in a 00144 * static context i.e. in a constructor. 00145 * 00146 * @code 00147 * uBit.init(); 00148 * @endcode 00149 * 00150 * @note This method must be called before user code utilises any functionality 00151 * contained by uBit. 00152 */ 00153 void init(); 00154 00155 /** 00156 * Return the friendly name for this device. 00157 * 00158 * @return A ManagedString representing the friendly name of this device. 00159 * 00160 * @code 00161 * ManagedString name = uBit.getName(); 00162 * @endcode 00163 */ 00164 static ManagedString getName(); 00165 00166 /** 00167 * Return the serial number of this device. 00168 * 00169 * @return A ManagedString representing the serial number of this device. 00170 * 00171 * @code 00172 * ManagedString serialNumber = uBit.getSerial(); 00173 * @endcode 00174 */ 00175 static ManagedString getSerial(); 00176 00177 /** 00178 * Will reset the micro:bit when called. 00179 * 00180 * @code 00181 * uBit.reset(); 00182 * @endcode 00183 */ 00184 void reset(); 00185 00186 /** 00187 * Delay execution for the given amount of time. 00188 * 00189 * If the scheduler is running, this will deschedule the current fiber and perform 00190 * a power efficient, concurrent sleep operation. 00191 * 00192 * If the scheduler is disabled or we're running in an interrupt context, this 00193 * will revert to a busy wait. 00194 * 00195 * Alternatively: wait, wait_ms, wait_us can be used which will perform a blocking sleep 00196 * operation. 00197 * 00198 * @param milliseconds the amount of time, in ms, to wait for. This number cannot be negative. 00199 * 00200 * @return MICROBIT_OK on success, MICROBIT_INVALID_PARAMETER milliseconds is less than zero. 00201 * 00202 * @code 00203 * uBit.sleep(20); //sleep for 20ms 00204 * @endcode 00205 * 00206 * @note This operation is currently limited by the rate of the system timer, therefore 00207 * the granularity of the sleep operation is limited to 6 ms unless the rate of 00208 * the system timer is modified. 00209 */ 00210 void sleep(uint32_t milliseconds); 00211 00212 /** 00213 * Seed the pseudo random number generator using the hardware random number generator. 00214 * 00215 * @code 00216 * uBit.seedRandom(); 00217 * @endcode 00218 */ 00219 void seedRandom(); 00220 00221 /** 00222 * Seed the pseudo random number generator using the given value. 00223 * 00224 * @param seed The 32-bit value to seed the generator with. 00225 * 00226 * @code 00227 * uBit.seedRandom(0xBB5EED); 00228 * @endcode 00229 */ 00230 void seedRandom(uint32_t seed); 00231 00232 00233 /** 00234 * Generate a random number in the given range. 00235 * We use a simple Galois LFSR random number generator here, 00236 * as a Galois LFSR is sufficient for our applications, and much more lightweight 00237 * than the hardware random number generator built int the processor, which takes 00238 * a long time and uses a lot of energy. 00239 * 00240 * KIDS: You shouldn't use this is the real world to generate cryptographic keys though... 00241 * have a think why not. :-) 00242 * 00243 * @param max the upper range to generate a number for. This number cannot be negative. 00244 * 00245 * @return A random, natural number between 0 and the max-1. Or MICROBIT_INVALID_VALUE if max is <= 0. 00246 * 00247 * @code 00248 * uBit.random(200); //a number between 0 and 199 00249 * @endcode 00250 */ 00251 int random(int max); 00252 00253 /** 00254 * Determine the time since this MicroBit was last reset. 00255 * 00256 * @return The time since the last reset, in milliseconds. 00257 * 00258 * @note This will value overflow after 1.6 months. 00259 */ 00260 //TODO: handle overflow case. 00261 unsigned long systemTime(); 00262 00263 /** 00264 * Determine the version of the micro:bit runtime currently in use. 00265 * 00266 * @return A textual description of the version of the micro:bit runtime that 00267 * is currently running on this device. 00268 */ 00269 const char *systemVersion(); 00270 00271 /** 00272 * Triggers a microbit panic where an loop will display a panic face 00273 * and the status code, if provided. 00274 * 00275 * This loop will continue for panic_timeout iterations, defaults to 0 (infinite). 00276 * 00277 * panic_timeout can be configured via a call to microbit_panic_timeout. 00278 * 00279 * @param statusCode the status code of the associated error. 00280 * 00281 * @code 00282 * microbit_panic_timeout(4); 00283 * 00284 * // will display loop for 4 iterations. 00285 * uBit.panic(10); 00286 * @endcode 00287 */ 00288 void panic(int statusCode = 0); 00289 00290 /** 00291 * Add a component to the array of system components. This component will then receive 00292 * periodic callbacks, once every tick period in interrupt context. 00293 * 00294 * @param component The component to add. 00295 * 00296 * @return MICROBIT_OK on success or MICROBIT_NO_RESOURCES if the component array is full. 00297 * 00298 * @code 00299 * // heap allocated - otherwise it will be paged out! 00300 * MicroBitDisplay* display = new MicroBitDisplay(); 00301 * 00302 * uBit.addSystemComponent(display); 00303 * @endcode 00304 * 00305 * @note This interface is now deprecated, and will be removed in the next major release. Please use system_timer_add_component(). 00306 */ 00307 int addSystemComponent(MicroBitComponent *component); 00308 00309 /** 00310 * Remove a component from the array of system components. This component will no longer receive 00311 * periodic callbacks. 00312 * 00313 * @param component The component to remove. 00314 * 00315 * @return MICROBIT_OK on success or MICROBIT_INVALID_PARAMETER is returned if the given component has not been previously added. 00316 * 00317 * @code 00318 * // heap allocated - otherwise it will be paged out! 00319 * MicroBitDisplay* display = new MicroBitDisplay(); 00320 * 00321 * uBit.addSystemComponent(display); 00322 * 00323 * uBit.removeSystemComponent(display); 00324 * @endcode 00325 * 00326 * @note This interface is now deprecated, and will be removed in the next major release. Please use system_timer_remove_component(). 00327 */ 00328 int removeSystemComponent(MicroBitComponent *component); 00329 00330 /** 00331 * Adds a component to the array of idle thread components, which are processed 00332 * when the run queue is empty. 00333 * 00334 * The system timer will poll isIdleCallbackNeeded on each component to determine 00335 * if the scheduler should schedule the idle_task imminently. 00336 * 00337 * @param component The component to add to the array. 00338 * 00339 * @return MICROBIT_OK on success or MICROBIT_NO_RESOURCES if the fiber components array is full. 00340 * 00341 * @code 00342 * MicroBitI2C i2c(I2C_SDA0, I2C_SCL0); 00343 * 00344 * // heap allocated - otherwise it will be paged out! 00345 * MicroBitAccelerometer* accelerometer = new MicroBitAccelerometer(i2c); 00346 * 00347 * fiber_add_idle_component(accelerometer); 00348 * @endcode 00349 * 00350 * @note This interface is now deprecated, and will be removed in the next major release. Please use fiber_add_idle_component(). 00351 */ 00352 int addIdleComponent(MicroBitComponent *component); 00353 00354 /** 00355 * Remove a component from the array of idle thread components 00356 * 00357 * @param component The component to remove from the idle component array. 00358 * 00359 * @return MICROBIT_OK on success. MICROBIT_INVALID_PARAMETER is returned if the given component has not been previously added. 00360 * 00361 * @code 00362 * MicroBitI2C i2c(I2C_SDA0, I2C_SCL0); 00363 * 00364 * // heap allocated - otherwise it will be paged out! 00365 * MicroBitAccelerometer* accelerometer = new MicroBitAccelerometer(i2c); 00366 * 00367 * uBit.addIdleComponent(accelerometer); 00368 * 00369 * uBit.removeIdleComponent(accelerometer); 00370 * @endcode 00371 * 00372 * @note This interface is now deprecated, and will be removed in the next major release. Please use fiber_remove_idle_component(). 00373 */ 00374 int removeIdleComponent(MicroBitComponent *component); 00375 }; 00376 00377 /** 00378 * Return the friendly name for this device. 00379 * 00380 * @return A ManagedString representing the friendly name of this device. 00381 * 00382 * @code 00383 * ManagedString name = uBit.getName(); 00384 * @endcode 00385 */ 00386 inline ManagedString MicroBit::getName() 00387 { 00388 return ManagedString(microbit_friendly_name()); 00389 } 00390 00391 /** 00392 * Return the serial number of this device. 00393 * 00394 * @return A ManagedString representing the serial number of this device. 00395 * 00396 * @code 00397 * ManagedString serialNumber = uBit.getSerial(); 00398 * @endcode 00399 */ 00400 inline ManagedString MicroBit::getSerial() 00401 { 00402 // We take to 16 bit numbers here, as we want the full range of ID bits, but don't want negative numbers... 00403 int n1 = microbit_serial_number() & 0xffff; 00404 int n2 = (microbit_serial_number() >> 16) & 0xffff; 00405 00406 // Simply concat the two numbers. 00407 ManagedString s1(n1); 00408 ManagedString s2(n2); 00409 00410 return s1 + s2; 00411 } 00412 00413 /** 00414 * Will reset the micro:bit when called. 00415 * 00416 * @code 00417 * uBit.reset(); 00418 * @endcode 00419 */ 00420 inline void MicroBit::reset() 00421 { 00422 if(ble && ble->getGapState().connected) { 00423 00424 // We have a connected BLE peer. Disconnect the BLE session. 00425 ble->gap().disconnect(Gap::REMOTE_USER_TERMINATED_CONNECTION); 00426 00427 // Wait a little while for the connection to drop. 00428 wait_ms(100); 00429 } 00430 00431 microbit_reset(); 00432 } 00433 00434 /** 00435 * Delay execution for the given amount of time. 00436 * 00437 * If the scheduler is running, this will deschedule the current fiber and perform 00438 * a power efficient, concurrent sleep operation. 00439 * 00440 * If the scheduler is disabled or we're running in an interrupt context, this 00441 * will revert to a busy wait. 00442 * 00443 * Alternatively: wait, wait_ms, wait_us can be used which will perform a blocking sleep 00444 * operation. 00445 * 00446 * @param milliseconds the amount of time, in ms, to wait for. This number cannot be negative. 00447 * 00448 * @return MICROBIT_OK on success, MICROBIT_INVALID_PARAMETER milliseconds is less than zero. 00449 * 00450 * @code 00451 * uBit.sleep(20); //sleep for 20ms 00452 * @endcode 00453 * 00454 * @note This operation is currently limited by the rate of the system timer, therefore 00455 * the granularity of the sleep operation is limited to 6 ms unless the rate of 00456 * the system timer is modified. 00457 */ 00458 inline void MicroBit::sleep(uint32_t milliseconds) 00459 { 00460 fiber_sleep(milliseconds); 00461 } 00462 00463 /** 00464 * Generate a random number in the given range. 00465 * We use a simple Galois LFSR random number generator here, 00466 * as a Galois LFSR is sufficient for our applications, and much more lightweight 00467 * than the hardware random number generator built int the processor, which takes 00468 * a long time and uses a lot of energy. 00469 * 00470 * KIDS: You shouldn't use this is the real world to generate cryptographic keys though... 00471 * have a think why not. :-) 00472 * 00473 * @param max the upper range to generate a number for. This number cannot be negative. 00474 * 00475 * @return A random, natural number between 0 and the max-1. Or MICROBIT_INVALID_VALUE if max is <= 0. 00476 * 00477 * @code 00478 * uBit.random(200); //a number between 0 and 199 00479 * @endcode 00480 */ 00481 inline int MicroBit::random(int max) 00482 { 00483 return microbit_random(max); 00484 } 00485 00486 /** 00487 * Seed the pseudo random number generator using the hardware random number generator. 00488 * 00489 * @code 00490 * uBit.seedRandom(); 00491 * @endcode 00492 */ 00493 inline void MicroBit::seedRandom() 00494 { 00495 microbit_seed_random(); 00496 } 00497 00498 00499 /** 00500 * Seed the pseudo random number generator using the given value. 00501 * 00502 * @param seed The 32-bit value to seed the generator with. 00503 * 00504 * @code 00505 * uBit.seedRandom(0xBB5EED); 00506 * @endcode 00507 */ 00508 inline void MicroBit::seedRandom(uint32_t seed) 00509 { 00510 microbit_seed_random(seed); 00511 } 00512 00513 00514 /** 00515 * Add a component to the array of system components. This component will then receive 00516 * periodic callbacks, once every tick period in interrupt context. 00517 * 00518 * @param component The component to add. 00519 * 00520 * @return MICROBIT_OK on success or MICROBIT_NO_RESOURCES if the component array is full. 00521 * 00522 * @code 00523 * // heap allocated - otherwise it will be paged out! 00524 * MicroBitDisplay* display = new MicroBitDisplay(); 00525 * 00526 * uBit.addSystemComponent(display); 00527 * @endcode 00528 * 00529 * @note This interface is now deprecated, and will be removed in the next major release. Please use system_timer_add_component(). 00530 */ 00531 inline int MicroBit::addSystemComponent(MicroBitComponent *component) 00532 { 00533 return system_timer_add_component(component); 00534 } 00535 00536 /** 00537 * Remove a component from the array of system components. This component will no longer receive 00538 * periodic callbacks. 00539 * 00540 * @param component The component to remove. 00541 * 00542 * @return MICROBIT_OK on success or MICROBIT_INVALID_PARAMETER is returned if the given component has not been previously added. 00543 * 00544 * @code 00545 * // heap allocated - otherwise it will be paged out! 00546 * MicroBitDisplay* display = new MicroBitDisplay(); 00547 * 00548 * uBit.addSystemComponent(display); 00549 * 00550 * uBit.removeSystemComponent(display); 00551 * @endcode 00552 * 00553 * @note This interface is now deprecated, and will be removed in the next major release. Please use system_timer_remove_component(). 00554 */ 00555 inline int MicroBit::removeSystemComponent(MicroBitComponent *component) 00556 { 00557 return system_timer_remove_component(component); 00558 } 00559 00560 /** 00561 * Adds a component to the array of idle thread components, which are processed 00562 * when the run queue is empty. 00563 * 00564 * The system timer will poll isIdleCallbackNeeded on each component to determine 00565 * if the scheduler should schedule the idle_task imminently. 00566 * 00567 * @param component The component to add to the array. 00568 * 00569 * @return MICROBIT_OK on success or MICROBIT_NO_RESOURCES if the fiber components array is full. 00570 * 00571 * @code 00572 * MicroBitI2C i2c(I2C_SDA0, I2C_SCL0); 00573 * 00574 * // heap allocated - otherwise it will be paged out! 00575 * MicroBitAccelerometer* accelerometer = new MicroBitAccelerometer(i2c); 00576 * 00577 * fiber_add_idle_component(accelerometer); 00578 * @endcode 00579 * 00580 * @note This interface is now deprecated, and will be removed in the next major release. Please use fiber_add_idle_component(). 00581 */ 00582 inline int MicroBit::addIdleComponent(MicroBitComponent *component) 00583 { 00584 return fiber_add_idle_component(component); 00585 } 00586 00587 /** 00588 * Remove a component from the array of idle thread components 00589 * 00590 * @param component The component to remove from the idle component array. 00591 * 00592 * @return MICROBIT_OK on success. MICROBIT_INVALID_PARAMETER is returned if the given component has not been previously added. 00593 * 00594 * @code 00595 * MicroBitI2C i2c(I2C_SDA0, I2C_SCL0); 00596 * 00597 * // heap allocated - otherwise it will be paged out! 00598 * MicroBitAccelerometer* accelerometer = new MicroBitAccelerometer(i2c); 00599 * 00600 * uBit.addIdleComponent(accelerometer); 00601 * 00602 * uBit.removeIdleComponent(accelerometer); 00603 * @endcode 00604 * 00605 * @note This interface is now deprecated, and will be removed in the next major release. Please use fiber_remove_idle_component(). 00606 */ 00607 inline int MicroBit::removeIdleComponent(MicroBitComponent *component) 00608 { 00609 return fiber_remove_idle_component(component); 00610 } 00611 00612 00613 /** 00614 * Determine the time since this MicroBit was last reset. 00615 * 00616 * @return The time since the last reset, in milliseconds. 00617 * 00618 * @note This will value overflow after 1.6 months. 00619 */ 00620 inline unsigned long MicroBit::systemTime() 00621 { 00622 return system_timer_current_time(); 00623 } 00624 00625 00626 /** 00627 * Determine the version of the micro:bit runtime currently in use. 00628 * 00629 * @return A textual description of the version of the micro:bit runtime that 00630 * is currently running on this device. 00631 */ 00632 inline const char *MicroBit::systemVersion() 00633 { 00634 return microbit_dal_version(); 00635 } 00636 00637 /** 00638 * Triggers a microbit panic where an loop will display a panic face 00639 * and the status code, if provided. 00640 * 00641 * This loop will continue for panic_timeout iterations, defaults to 0 (infinite). 00642 * 00643 * panic_timeout can be configured via a call to microbit_panic_timeout. 00644 * 00645 * @param statusCode the status code of the associated error. 00646 * 00647 * @code 00648 * microbit_panic_timeout(4); 00649 * 00650 * // will display loop for 4 iterations. 00651 * uBit.panic(10); 00652 * @endcode 00653 */ 00654 inline void MicroBit::panic(int statusCode) 00655 { 00656 //show error and enter infinite while 00657 microbit_panic(statusCode); 00658 } 00659 00660 #endif
Generated on Wed Jul 13 2022 20:17:43 by 1.7.2