Attempting to publish a tree

Dependencies:   BLE_API mbed-dev-bin nRF51822

Fork of microbit-dal by Lancaster University

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MicroBitDisplay.h Source File

MicroBitDisplay.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_DISPLAY_H
00027 #define MICROBIT_DISPLAY_H
00028 
00029 #include "mbed.h"
00030 #include "MicroBitConfig.h"
00031 #include "ManagedString.h"
00032 #include "MicroBitComponent.h"
00033 #include "MicroBitImage.h"
00034 #include "MicroBitFont.h"
00035 #include "MicroBitMatrixMaps.h"
00036 #include "MicroBitLightSensor.h"
00037 
00038 /**
00039   * Event codes raised by MicroBitDisplay
00040   */
00041 #define MICROBIT_DISPLAY_EVT_ANIMATION_COMPLETE         1
00042 #define MICROBIT_DISPLAY_EVT_LIGHT_SENSE                2
00043 
00044 //
00045 // Internal constants
00046 //
00047 
00048 #define MICROBIT_DISPLAY_SPACING                1
00049 #define MICROBIT_DISPLAY_GREYSCALE_BIT_DEPTH    8
00050 #define MICROBIT_DISPLAY_ANIMATE_DEFAULT_POS    -255
00051 
00052 enum AnimationMode {
00053     ANIMATION_MODE_NONE,
00054     ANIMATION_MODE_STOPPED,
00055     ANIMATION_MODE_SCROLL_TEXT,
00056     ANIMATION_MODE_PRINT_TEXT,
00057     ANIMATION_MODE_SCROLL_IMAGE,
00058     ANIMATION_MODE_ANIMATE_IMAGE,
00059     ANIMATION_MODE_PRINT_CHARACTER
00060 };
00061 
00062 enum DisplayMode {
00063     DISPLAY_MODE_BLACK_AND_WHITE,
00064     DISPLAY_MODE_GREYSCALE,
00065     DISPLAY_MODE_BLACK_AND_WHITE_LIGHT_SENSE
00066 };
00067 
00068 enum DisplayRotation {
00069     MICROBIT_DISPLAY_ROTATION_0,
00070     MICROBIT_DISPLAY_ROTATION_90,
00071     MICROBIT_DISPLAY_ROTATION_180,
00072     MICROBIT_DISPLAY_ROTATION_270
00073 };
00074 
00075 /**
00076   * Class definition for MicroBitDisplay.
00077   *
00078   * A MicroBitDisplay represents the LED matrix array on the micro:bit.
00079   */
00080 class MicroBitDisplay : public MicroBitComponent
00081 {
00082     uint8_t width;
00083     uint8_t height;
00084     uint8_t brightness;
00085     uint8_t strobeRow;
00086     uint8_t rotation;
00087     uint8_t mode;
00088     uint8_t greyscaleBitMsk;
00089     uint8_t timingCount;
00090     uint32_t col_mask;
00091 
00092     Timeout renderTimer;
00093     PortOut *LEDMatrix;
00094 
00095     //
00096     // State used by all animation routines.
00097     //
00098 
00099     // The animation mode that's currently running (if any)
00100     volatile AnimationMode animationMode;
00101 
00102     // The time in milliseconds between each frame update.
00103     uint16_t animationDelay;
00104 
00105     // The time in milliseconds since the frame update.
00106     uint16_t animationTick;
00107 
00108     // Stop playback of any animations
00109     void stopAnimation(int delay);
00110 
00111     //
00112     // State for scrollString() method.
00113     // This is a surprisingly intricate method.
00114     //
00115     // The text being displayed.
00116     ManagedString scrollingText;
00117 
00118     // The index of the character currently being displayed.
00119     uint16_t scrollingChar;
00120 
00121     // The number of pixels the current character has been shifted on the display.
00122     uint8_t scrollingPosition;
00123 
00124     //
00125     // State for printString() method.
00126     //
00127     // The text being displayed. NULL if no message is scheduled for playback.
00128     // We *could* get some reuse in here with the scroll* variables above,
00129     // but best to keep it clean in case kids try concurrent operation (they will!),
00130     // given the small RAM overhead needed to maintain orthogonality.
00131     ManagedString printingText;
00132 
00133     // The index of the character currently being displayed.
00134     uint16_t printingChar;
00135 
00136     //
00137     // State for scrollImage() method.
00138     //
00139     // The image being displayed.
00140     MicroBitImage scrollingImage;
00141 
00142     // The number of pixels the image has been shifted on the display.
00143     int16_t scrollingImagePosition;
00144 
00145     // The number of pixels the image is shifted on the display in each quantum.
00146     int8_t scrollingImageStride;
00147 
00148     // A pointer to an instance of light sensor, if in use
00149     MicroBitLightSensor* lightSensor;
00150 
00151     // Flag to indicate if image has been rendered to screen yet (or not)
00152     bool scrollingImageRendered;
00153 
00154     const MatrixMap &matrixMap;
00155 
00156     // Internal methods to handle animation.
00157 
00158     /**
00159       *  Periodic callback, that we use to perform any animations we have running.
00160       */
00161     void animationUpdate();
00162 
00163     /**
00164       *  Called by the display in an interval determined by the brightness of the display, to give an impression
00165       *  of brightness.
00166       */
00167     void renderFinish();
00168 
00169     /**
00170       * Translates a bit mask to a bit mask suitable for the nrf PORT0 and PORT1.
00171       * Brightness has two levels on, or off.
00172       */
00173     void render();
00174 
00175     /**
00176       * Renders the current image, and drops the fourth frame to allow for
00177       * sensors that require the display to operate.
00178       */
00179     void renderWithLightSense();
00180 
00181     /**
00182       * Translates a bit mask into a timer interrupt that gives the appearence of greyscale.
00183       */
00184     void renderGreyscale();
00185 
00186     /**
00187       * Internal scrollText update method.
00188       * Shift the screen image by one pixel to the left. If necessary, paste in the next char.
00189       */
00190     void updateScrollText();
00191 
00192     /**
00193       * Internal printText update method.
00194       * Paste the next character in the string.
00195       */
00196     void updatePrintText();
00197 
00198     /**
00199       * Internal scrollImage update method.
00200       * Paste the stored bitmap at the appropriate point.
00201       */
00202     void updateScrollImage();
00203 
00204     /**
00205       * Internal animateImage update method.
00206       * Paste the stored bitmap at the appropriate point and stop on the last frame.
00207       */
00208     void updateAnimateImage();
00209 
00210     /**
00211      * Broadcasts an event onto the defult EventModel indicating that the
00212      * current animation has completed.
00213      */
00214     void sendAnimationCompleteEvent();
00215 
00216     /**
00217       * Blocks the current fiber until the display is available (i.e. does not effect is being displayed).
00218       * Animations are queued until their time to display.
00219       */
00220     void waitForFreeDisplay();
00221 
00222     /**
00223       * Blocks the current fiber until the current animation has finished.
00224       * If the scheduler is not running, this call will essentially perform a spinning wait.
00225       */
00226     void fiberWait();
00227 
00228     /**
00229       * Enables or disables the display entirely, and releases the pins for other uses.
00230       *
00231       * @param enableDisplay true to enabled the display, or false to disable it.
00232       */
00233     void setEnable(bool enableDisplay);
00234 
00235 public:
00236     // The mutable bitmap buffer being rendered to the LED matrix.
00237     MicroBitImage image;
00238 
00239     /**
00240       * Constructor.
00241       *
00242       * Create a software representation the micro:bit's 5x5 LED matrix.
00243       * The display is initially blank.
00244       *
00245       * @param id The id the display should use when sending events on the MessageBus. Defaults to MICROBIT_ID_DISPLAY.
00246       *
00247       * @param map The mapping information that relates pin inputs/outputs to physical screen coordinates.
00248       *            Defaults to microbitMatrixMap, defined in MicroBitMatrixMaps.h.
00249       *
00250       * @code
00251       * MicroBitDisplay display;
00252       * @endcode
00253       */
00254     MicroBitDisplay(uint16_t id = MICROBIT_ID_DISPLAY, const MatrixMap &map = microbitMatrixMap);
00255 
00256     /**
00257       * Stops any currently running animation, and any that are waiting to be displayed.
00258       */
00259     void stopAnimation();
00260 
00261     /**
00262       * Frame update method, invoked periodically to strobe the display.
00263       */
00264     virtual void systemTick();
00265 
00266     /**
00267       * Prints the given character to the display, if it is not in use.
00268       *
00269       * @param c The character to display.
00270       *
00271       * @param delay Optional parameter - the time for which to show the character. Zero displays the character forever,
00272       *              or until the Displays next use.
00273       *
00274       * @return MICROBIT_OK, MICROBIT_BUSY is the screen is in use, or MICROBIT_INVALID_PARAMETER.
00275       *
00276       * @code
00277       * display.printAsync('p');
00278       * display.printAsync('p',100);
00279       * @endcode
00280       */
00281     int printCharAsync(char c, int delay = 0);
00282 
00283     /**
00284       * Prints the given ManagedString to the display, one character at a time.
00285       * Returns immediately, and executes the animation asynchronously.
00286       *
00287       * @param s The string to display.
00288       *
00289       * @param delay The time to delay between characters, in milliseconds. Must be > 0.
00290       *              Defaults to: MICROBIT_DEFAULT_PRINT_SPEED.
00291       *
00292       * @return MICROBIT_OK, or MICROBIT_INVALID_PARAMETER.
00293       *
00294       * @code
00295       * display.printAsync("abc123",400);
00296       * @endcode
00297       */
00298     int printAsync(ManagedString s, int delay = MICROBIT_DEFAULT_PRINT_SPEED);
00299 
00300     /**
00301       * Prints the given image to the display, if the display is not in use.
00302       * Returns immediately, and executes the animation asynchronously.
00303       *
00304       * @param i The image to display.
00305       *
00306       * @param x The horizontal position on the screen to display the image. Defaults to 0.
00307       *
00308       * @param y The vertical position on the screen to display the image. Defaults to 0.
00309       *
00310       * @param alpha Treats the brightness level '0' as transparent. Defaults to 0.
00311       *
00312       * @param delay The time to delay between characters, in milliseconds. Defaults to 0.
00313       *
00314       * @code
00315       * MicrobitImage i("1,1,1,1,1\n1,1,1,1,1\n");
00316       * display.print(i,400);
00317       * @endcode
00318       */
00319     int printAsync(MicroBitImage i, int x = 0, int y = 0, int alpha = 0, int delay = 0);
00320 
00321     /**
00322       * Prints the given character to the display.
00323       *
00324       * @param c The character to display.
00325       *
00326       * @param delay Optional parameter - the time for which to show the character. Zero displays the character forever,
00327       *              or until the Displays next use.
00328       *
00329       * @return MICROBIT_OK, MICROBIT_CANCELLED or MICROBIT_INVALID_PARAMETER.
00330       *
00331       * @code
00332       * display.printAsync('p');
00333       * display.printAsync('p',100);
00334       * @endcode
00335       */
00336     int printChar(char c, int delay = 0);
00337 
00338     /**
00339       * Prints the given string to the display, one character at a time.
00340       *
00341       * Blocks the calling thread until all the text has been displayed.
00342       *
00343       * @param s The string to display.
00344       *
00345       * @param delay The time to delay between characters, in milliseconds. Defaults
00346       *              to: MICROBIT_DEFAULT_PRINT_SPEED.
00347       *
00348       * @return MICROBIT_OK, MICROBIT_CANCELLED or MICROBIT_INVALID_PARAMETER.
00349       *
00350       * @code
00351       * display.print("abc123",400);
00352       * @endcode
00353       */
00354     int print(ManagedString s, int delay = MICROBIT_DEFAULT_PRINT_SPEED);
00355 
00356     /**
00357       * Prints the given image to the display.
00358       * Blocks the calling thread until all the image has been displayed.
00359       *
00360       * @param i The image to display.
00361       *
00362       * @param x The horizontal position on the screen to display the image. Defaults to 0.
00363       *
00364       * @param y The vertical position on the screen to display the image. Defaults to 0.
00365       *
00366       * @param alpha Treats the brightness level '0' as transparent. Defaults to 0.
00367       *
00368       * @param delay The time to display the image for, or zero to show the image forever. Defaults to 0.
00369       *
00370       * @return MICROBIT_OK, MICROBIT_BUSY if the display is already in use, or MICROBIT_INVALID_PARAMETER.
00371       *
00372       * @code
00373       * MicrobitImage i("1,1,1,1,1\n1,1,1,1,1\n");
00374       * display.print(i,400);
00375       * @endcode
00376       */
00377     int print(MicroBitImage i, int x = 0, int y = 0, int alpha = 0, int delay = 0);
00378 
00379     /**
00380       * Scrolls the given string to the display, from right to left.
00381       * Returns immediately, and executes the animation asynchronously.
00382       *
00383       * @param s The string to display.
00384       *
00385       * @param delay The time to delay between characters, in milliseconds. Defaults
00386       *              to: MICROBIT_DEFAULT_SCROLL_SPEED.
00387       *
00388       * @return MICROBIT_OK, MICROBIT_BUSY if the display is already in use, or MICROBIT_INVALID_PARAMETER.
00389       *
00390       * @code
00391       * display.scrollAsync("abc123",100);
00392       * @endcode
00393       */
00394     int scrollAsync(ManagedString s, int delay = MICROBIT_DEFAULT_SCROLL_SPEED);
00395 
00396     /**
00397       * Scrolls the given image across the display, from right to left.
00398       * Returns immediately, and executes the animation asynchronously.
00399       *
00400       * @param image The image to display.
00401       *
00402       * @param delay The time between updates, in milliseconds. Defaults
00403       *              to: MICROBIT_DEFAULT_SCROLL_SPEED.
00404       *
00405       * @param stride The number of pixels to shift by in each update. Defaults to MICROBIT_DEFAULT_SCROLL_STRIDE.
00406       *
00407       * @return MICROBIT_OK, MICROBIT_BUSY if the display is already in use, or MICROBIT_INVALID_PARAMETER.
00408       *
00409       * @code
00410       * MicrobitImage i("1,1,1,1,1\n1,1,1,1,1\n");
00411       * display.scrollAsync(i,100,1);
00412       * @endcode
00413       */
00414     int scrollAsync(MicroBitImage image, int delay = MICROBIT_DEFAULT_SCROLL_SPEED, int stride = MICROBIT_DEFAULT_SCROLL_STRIDE);
00415 
00416     /**
00417       * Scrolls the given string across the display, from right to left.
00418       * Blocks the calling thread until all text has been displayed.
00419       *
00420       * @param s The string to display.
00421       *
00422       * @param delay The time to delay between characters, in milliseconds. Defaults
00423       *              to: MICROBIT_DEFAULT_SCROLL_SPEED.
00424       *
00425       * @return MICROBIT_OK, MICROBIT_CANCELLED or MICROBIT_INVALID_PARAMETER.
00426       *
00427       * @code
00428       * display.scroll("abc123",100);
00429       * @endcode
00430       */
00431     int scroll(ManagedString s, int delay = MICROBIT_DEFAULT_SCROLL_SPEED);
00432 
00433     /**
00434       * Scrolls the given image across the display, from right to left.
00435       * Blocks the calling thread until all the text has been displayed.
00436       *
00437       * @param image The image to display.
00438       *
00439       * @param delay The time between updates, in milliseconds. Defaults
00440       *              to: MICROBIT_DEFAULT_SCROLL_SPEED.
00441       *
00442       * @param stride The number of pixels to shift by in each update. Defaults to MICROBIT_DEFAULT_SCROLL_STRIDE.
00443       *
00444       * @return MICROBIT_OK, MICROBIT_CANCELLED or MICROBIT_INVALID_PARAMETER.
00445       *
00446       * @code
00447       * MicrobitImage i("1,1,1,1,1\n1,1,1,1,1\n");
00448       * display.scroll(i,100,1);
00449       * @endcode
00450       */
00451     int scroll(MicroBitImage image, int delay = MICROBIT_DEFAULT_SCROLL_SPEED, int stride = MICROBIT_DEFAULT_SCROLL_STRIDE);
00452 
00453     /**
00454       * "Animates" the current image across the display with a given stride, finishing on the last frame of the animation.
00455       * Returns immediately.
00456       *
00457       * @param image The image to display.
00458       *
00459       * @param delay The time to delay between each update of the display, in milliseconds.
00460       *
00461       * @param stride The number of pixels to shift by in each update.
00462       *
00463       * @param startingPosition the starting position on the display for the animation
00464       *                         to begin at. Defaults to MICROBIT_DISPLAY_ANIMATE_DEFAULT_POS.
00465       *
00466       * @return MICROBIT_OK, MICROBIT_BUSY if the screen is in use, or MICROBIT_INVALID_PARAMETER.
00467       *
00468       * @code
00469       * const int heart_w = 10;
00470       * const int heart_h = 5;
00471       * const uint8_t heart[] = { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, };
00472       *
00473       * MicroBitImage i(heart_w,heart_h,heart);
00474       * display.animateAsync(i,100,5);
00475       * @endcode
00476       */
00477     int animateAsync(MicroBitImage image, int delay, int stride, int startingPosition = MICROBIT_DISPLAY_ANIMATE_DEFAULT_POS);
00478 
00479     /**
00480       * "Animates" the current image across the display with a given stride, finishing on the last frame of the animation.
00481       * Blocks the calling thread until the animation is complete.
00482       *
00483       *
00484       * @param delay The time to delay between each update of the display, in milliseconds.
00485       *
00486       * @param stride The number of pixels to shift by in each update.
00487       *
00488       * @param startingPosition the starting position on the display for the animation
00489       *                         to begin at. Defaults to MICROBIT_DISPLAY_ANIMATE_DEFAULT_POS.
00490       *
00491       * @return MICROBIT_OK, MICROBIT_CANCELLED or MICROBIT_INVALID_PARAMETER.
00492       *
00493       * @code
00494       * const int heart_w = 10;
00495       * const int heart_h = 5;
00496       * const uint8_t heart[] = { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, };
00497       *
00498       * MicroBitImage i(heart_w,heart_h,heart);
00499       * display.animate(i,100,5);
00500       * @endcode
00501       */
00502     int animate(MicroBitImage image, int delay, int stride, int startingPosition = MICROBIT_DISPLAY_ANIMATE_DEFAULT_POS);
00503 
00504     /**
00505       * Configures the brightness of the display.
00506       *
00507       * @param b The brightness to set the brightness to, in the range 0 - 255.
00508       *
00509       * @return MICROBIT_OK, or MICROBIT_INVALID_PARAMETER
00510       *
00511       * @code
00512       * display.setBrightness(255); //max brightness
00513       * @endcode
00514       */
00515     int setBrightness(int b);
00516 
00517     /**
00518       * Configures the mode of the display.
00519       *
00520       * @param mode The mode to swap the display into. One of: DISPLAY_MODE_GREYSCALE,
00521       *             DISPLAY_MODE_BLACK_AND_WHITE, DISPLAY_MODE_BLACK_AND_WHITE_LIGHT_SENSE
00522       *
00523       * @code
00524       * display.setDisplayMode(DISPLAY_MODE_GREYSCALE); //per pixel brightness
00525       * @endcode
00526       */
00527     void setDisplayMode(DisplayMode mode);
00528 
00529     /**
00530       * Retrieves the mode of the display.
00531       *
00532       * @return the current mode of the display
00533       */
00534     int getDisplayMode();
00535 
00536     /**
00537       * Fetches the current brightness of this display.
00538       *
00539       * @return the brightness of this display, in the range 0..255.
00540       *
00541       * @code
00542       * display.getBrightness(); //the current brightness
00543       * @endcode
00544       */
00545     int getBrightness();
00546 
00547     /**
00548       * Rotates the display to the given position.
00549       *
00550       * Axis aligned values only.
00551       *
00552       * @code
00553       * display.rotateTo(MICROBIT_DISPLAY_ROTATION_180); //rotates 180 degrees from original orientation
00554       * @endcode
00555       */
00556     void rotateTo(DisplayRotation position);
00557 
00558     /**
00559       * Enables the display, should only be called if the display is disabled.
00560       *
00561       * @code
00562       * display.enable(); //Enables the display mechanics
00563       * @endcode
00564       *
00565       * @note Only enables the display if the display is currently disabled.
00566       */
00567     void enable();
00568 
00569     /**
00570       * Disables the display, which releases control of the GPIO pins used by the display,
00571       * which are exposed on the edge connector.
00572       *
00573       * @code
00574       * display.disable(); //disables the display
00575       * @endcode
00576       *
00577       * @note Only disables the display if the display is currently enabled.
00578       */
00579     void disable();
00580 
00581     /**
00582       * Clears the display of any remaining pixels.
00583       *
00584       * `display.image.clear()` can also be used!
00585       *
00586       * @code
00587       * display.clear(); //clears the display
00588       * @endcode
00589       */
00590     void clear();
00591 
00592     /**
00593       * Updates the font that will be used for display operations.
00594       *
00595       * @param font the new font that will be used to render characters.
00596       *
00597       * @note DEPRECATED! Please use MicroBitFont::setSystemFont() instead.
00598       */
00599     void setFont(MicroBitFont font);
00600 
00601     /**
00602       * Retrieves the font object used for rendering characters on the display.
00603       *
00604       * @note DEPRECATED! Please use MicroBitFont::getSystemFont() instead.
00605       */
00606     MicroBitFont getFont();
00607 
00608     /**
00609       * Captures the bitmap currently being rendered on the display.
00610       *
00611       * @return a MicroBitImage containing the captured data.
00612       */
00613     MicroBitImage screenShot();
00614 
00615     /**
00616       * Gives a representative figure of the light level in the current environment
00617       * where are micro:bit is situated.
00618       *
00619       * Internally, it constructs an instance of a MicroBitLightSensor if not already configured
00620       * and sets the display mode to DISPLAY_MODE_BLACK_AND_WHITE_LIGHT_SENSE.
00621       *
00622       * This also changes the tickPeriod to MICROBIT_LIGHT_SENSOR_TICK_SPEED so
00623       * that the display does not suffer from artifacts.
00624       *
00625       * @return an indicative light level in the range 0 - 255.
00626       *
00627       * @note this will return 0 on the first call to this method, a light reading
00628       * will be available after the display has activated the light sensor for the
00629       * first time.
00630       */
00631     int readLightLevel();
00632 
00633     /**
00634       * Destructor for MicroBitDisplay, where we deregister this instance from the array of system components.
00635       */
00636     ~MicroBitDisplay();
00637 };
00638 
00639 #endif