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