No Changes

Dependencies:   BLE_API mbed-dev-bin nRF51822

Dependents:   microbit

Fork of microbit-dal by Lancaster University

Committer:
Jonathan Austin
Date:
Thu Apr 07 01:33:22 2016 +0100
Revision:
1:8aa5cdb4ab67
Child:
20:ad2a5c7debf4
Synchronized with git rev 55cb9199

Who changed what in which revision?

UserRevisionLine numberNew 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 /**
Jonathan Austin 1:8aa5cdb4ab67 27 * Class definition for MicroBitDisplay.
Jonathan Austin 1:8aa5cdb4ab67 28 *
Jonathan Austin 1:8aa5cdb4ab67 29 * A MicroBitDisplay represents the LED matrix array on the micro:bit.
Jonathan Austin 1:8aa5cdb4ab67 30 */
Jonathan Austin 1:8aa5cdb4ab67 31 #include "MicroBitConfig.h"
Jonathan Austin 1:8aa5cdb4ab67 32 #include "MicroBitDisplay.h"
Jonathan Austin 1:8aa5cdb4ab67 33 #include "MicroBitSystemTimer.h"
Jonathan Austin 1:8aa5cdb4ab67 34 #include "MicroBitFiber.h"
Jonathan Austin 1:8aa5cdb4ab67 35 #include "ErrorNo.h"
Jonathan Austin 1:8aa5cdb4ab67 36 #include "NotifyEvents.h"
Jonathan Austin 1:8aa5cdb4ab67 37
Jonathan Austin 1:8aa5cdb4ab67 38 const int greyScaleTimings[MICROBIT_DISPLAY_GREYSCALE_BIT_DEPTH] = {1, 23, 70, 163, 351, 726, 1476, 2976};
Jonathan Austin 1:8aa5cdb4ab67 39
Jonathan Austin 1:8aa5cdb4ab67 40 /**
Jonathan Austin 1:8aa5cdb4ab67 41 * Constructor.
Jonathan Austin 1:8aa5cdb4ab67 42 *
Jonathan Austin 1:8aa5cdb4ab67 43 * Create a software representation the micro:bit's 5x5 LED matrix.
Jonathan Austin 1:8aa5cdb4ab67 44 * The display is initially blank.
Jonathan Austin 1:8aa5cdb4ab67 45 *
Jonathan Austin 1:8aa5cdb4ab67 46 * @param id The id the display should use when sending events on the MessageBus. Defaults to MICROBIT_ID_DISPLAY.
Jonathan Austin 1:8aa5cdb4ab67 47 *
Jonathan Austin 1:8aa5cdb4ab67 48 * @param map The mapping information that relates pin inputs/outputs to physical screen coordinates.
Jonathan Austin 1:8aa5cdb4ab67 49 * Defaults to microbitMatrixMap, defined in MicroBitMatrixMaps.h.
Jonathan Austin 1:8aa5cdb4ab67 50 *
Jonathan Austin 1:8aa5cdb4ab67 51 * @code
Jonathan Austin 1:8aa5cdb4ab67 52 * MicroBitDisplay display;
Jonathan Austin 1:8aa5cdb4ab67 53 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 54 */
Jonathan Austin 1:8aa5cdb4ab67 55 MicroBitDisplay::MicroBitDisplay(uint16_t id, const MatrixMap &map) :
Jonathan Austin 1:8aa5cdb4ab67 56 matrixMap(map),
Jonathan Austin 1:8aa5cdb4ab67 57 image(map.width*2,map.height)
Jonathan Austin 1:8aa5cdb4ab67 58 {
Jonathan Austin 1:8aa5cdb4ab67 59 uint32_t row_mask;
Jonathan Austin 1:8aa5cdb4ab67 60
Jonathan Austin 1:8aa5cdb4ab67 61 this->id = id;
Jonathan Austin 1:8aa5cdb4ab67 62 this->width = map.width;
Jonathan Austin 1:8aa5cdb4ab67 63 this->height = map.height;
Jonathan Austin 1:8aa5cdb4ab67 64 this->rotation = MICROBIT_DISPLAY_ROTATION_0;
Jonathan Austin 1:8aa5cdb4ab67 65
Jonathan Austin 1:8aa5cdb4ab67 66 row_mask = 0;
Jonathan Austin 1:8aa5cdb4ab67 67 col_mask = 0;
Jonathan Austin 1:8aa5cdb4ab67 68 strobeRow = 0;
Jonathan Austin 1:8aa5cdb4ab67 69 row_mask = 0;
Jonathan Austin 1:8aa5cdb4ab67 70
Jonathan Austin 1:8aa5cdb4ab67 71 for (int i = matrixMap.rowStart; i < matrixMap.rowStart + matrixMap.rows; i++)
Jonathan Austin 1:8aa5cdb4ab67 72 row_mask |= 0x01 << i;
Jonathan Austin 1:8aa5cdb4ab67 73
Jonathan Austin 1:8aa5cdb4ab67 74 for (int i = matrixMap.columnStart; i < matrixMap.columnStart + matrixMap.columns; i++)
Jonathan Austin 1:8aa5cdb4ab67 75 col_mask |= 0x01 << i;
Jonathan Austin 1:8aa5cdb4ab67 76
Jonathan Austin 1:8aa5cdb4ab67 77 LEDMatrix = new PortOut(Port0, row_mask | col_mask);
Jonathan Austin 1:8aa5cdb4ab67 78
Jonathan Austin 1:8aa5cdb4ab67 79 this->greyscaleBitMsk = 0x01;
Jonathan Austin 1:8aa5cdb4ab67 80 this->timingCount = 0;
Jonathan Austin 1:8aa5cdb4ab67 81 this->setBrightness(MICROBIT_DISPLAY_DEFAULT_BRIGHTNESS);
Jonathan Austin 1:8aa5cdb4ab67 82 this->mode = DISPLAY_MODE_BLACK_AND_WHITE;
Jonathan Austin 1:8aa5cdb4ab67 83 this->animationMode = ANIMATION_MODE_NONE;
Jonathan Austin 1:8aa5cdb4ab67 84 this->lightSensor = NULL;
Jonathan Austin 1:8aa5cdb4ab67 85
Jonathan Austin 1:8aa5cdb4ab67 86 system_timer_add_component(this);
Jonathan Austin 1:8aa5cdb4ab67 87
Jonathan Austin 1:8aa5cdb4ab67 88 status |= MICROBIT_COMPONENT_RUNNING;
Jonathan Austin 1:8aa5cdb4ab67 89 }
Jonathan Austin 1:8aa5cdb4ab67 90
Jonathan Austin 1:8aa5cdb4ab67 91 /**
Jonathan Austin 1:8aa5cdb4ab67 92 * Internal frame update method, used to strobe the display.
Jonathan Austin 1:8aa5cdb4ab67 93 *
Jonathan Austin 1:8aa5cdb4ab67 94 * TODO: Write a more efficient, complementary variation of this method for the case where
Jonathan Austin 1:8aa5cdb4ab67 95 * MICROBIT_DISPLAY_ROW_COUNT > MICROBIT_DISPLAY_COLUMN_COUNT.
Jonathan Austin 1:8aa5cdb4ab67 96 */
Jonathan Austin 1:8aa5cdb4ab67 97 void MicroBitDisplay::systemTick()
Jonathan Austin 1:8aa5cdb4ab67 98 {
Jonathan Austin 1:8aa5cdb4ab67 99 if(!(status & MICROBIT_COMPONENT_RUNNING))
Jonathan Austin 1:8aa5cdb4ab67 100 return;
Jonathan Austin 1:8aa5cdb4ab67 101
Jonathan Austin 1:8aa5cdb4ab67 102 if(mode == DISPLAY_MODE_BLACK_AND_WHITE_LIGHT_SENSE)
Jonathan Austin 1:8aa5cdb4ab67 103 {
Jonathan Austin 1:8aa5cdb4ab67 104 renderWithLightSense();
Jonathan Austin 1:8aa5cdb4ab67 105 return;
Jonathan Austin 1:8aa5cdb4ab67 106 }
Jonathan Austin 1:8aa5cdb4ab67 107
Jonathan Austin 1:8aa5cdb4ab67 108 // Move on to the next row.
Jonathan Austin 1:8aa5cdb4ab67 109 strobeRow++;
Jonathan Austin 1:8aa5cdb4ab67 110
Jonathan Austin 1:8aa5cdb4ab67 111 //reset the row counts and bit mask when we have hit the max.
Jonathan Austin 1:8aa5cdb4ab67 112 if(strobeRow == matrixMap.rows)
Jonathan Austin 1:8aa5cdb4ab67 113 strobeRow = 0;
Jonathan Austin 1:8aa5cdb4ab67 114
Jonathan Austin 1:8aa5cdb4ab67 115 if(mode == DISPLAY_MODE_BLACK_AND_WHITE)
Jonathan Austin 1:8aa5cdb4ab67 116 render();
Jonathan Austin 1:8aa5cdb4ab67 117
Jonathan Austin 1:8aa5cdb4ab67 118 if(mode == DISPLAY_MODE_GREYSCALE)
Jonathan Austin 1:8aa5cdb4ab67 119 {
Jonathan Austin 1:8aa5cdb4ab67 120 greyscaleBitMsk = 0x01;
Jonathan Austin 1:8aa5cdb4ab67 121 timingCount = 0;
Jonathan Austin 1:8aa5cdb4ab67 122 renderGreyscale();
Jonathan Austin 1:8aa5cdb4ab67 123 }
Jonathan Austin 1:8aa5cdb4ab67 124
Jonathan Austin 1:8aa5cdb4ab67 125 // Update text and image animations if we need to.
Jonathan Austin 1:8aa5cdb4ab67 126 this->animationUpdate();
Jonathan Austin 1:8aa5cdb4ab67 127 }
Jonathan Austin 1:8aa5cdb4ab67 128
Jonathan Austin 1:8aa5cdb4ab67 129 void MicroBitDisplay::renderFinish()
Jonathan Austin 1:8aa5cdb4ab67 130 {
Jonathan Austin 1:8aa5cdb4ab67 131 *LEDMatrix = 0;
Jonathan Austin 1:8aa5cdb4ab67 132 }
Jonathan Austin 1:8aa5cdb4ab67 133
Jonathan Austin 1:8aa5cdb4ab67 134 void MicroBitDisplay::render()
Jonathan Austin 1:8aa5cdb4ab67 135 {
Jonathan Austin 1:8aa5cdb4ab67 136 // Simple optimisation.
Jonathan Austin 1:8aa5cdb4ab67 137 // If display is at zero brightness, there's nothing to do.
Jonathan Austin 1:8aa5cdb4ab67 138 if(brightness == 0)
Jonathan Austin 1:8aa5cdb4ab67 139 return;
Jonathan Austin 1:8aa5cdb4ab67 140
Jonathan Austin 1:8aa5cdb4ab67 141 // Calculate the bitpattern to write.
Jonathan Austin 1:8aa5cdb4ab67 142 uint32_t row_data = 0x01 << (microbitMatrixMap.rowStart + strobeRow);
Jonathan Austin 1:8aa5cdb4ab67 143 uint32_t col_data = 0;
Jonathan Austin 1:8aa5cdb4ab67 144
Jonathan Austin 1:8aa5cdb4ab67 145 for (int i = 0; i < matrixMap.columns; i++)
Jonathan Austin 1:8aa5cdb4ab67 146 {
Jonathan Austin 1:8aa5cdb4ab67 147 int index = (i * matrixMap.rows) + strobeRow;
Jonathan Austin 1:8aa5cdb4ab67 148
Jonathan Austin 1:8aa5cdb4ab67 149 int x = matrixMap.map[index].x;
Jonathan Austin 1:8aa5cdb4ab67 150 int y = matrixMap.map[index].y;
Jonathan Austin 1:8aa5cdb4ab67 151 int t = x;
Jonathan Austin 1:8aa5cdb4ab67 152
Jonathan Austin 1:8aa5cdb4ab67 153 if(rotation == MICROBIT_DISPLAY_ROTATION_90)
Jonathan Austin 1:8aa5cdb4ab67 154 {
Jonathan Austin 1:8aa5cdb4ab67 155 x = width - 1 - y;
Jonathan Austin 1:8aa5cdb4ab67 156 y = t;
Jonathan Austin 1:8aa5cdb4ab67 157 }
Jonathan Austin 1:8aa5cdb4ab67 158
Jonathan Austin 1:8aa5cdb4ab67 159 if(rotation == MICROBIT_DISPLAY_ROTATION_180)
Jonathan Austin 1:8aa5cdb4ab67 160 {
Jonathan Austin 1:8aa5cdb4ab67 161 x = width - 1 - x;
Jonathan Austin 1:8aa5cdb4ab67 162 y = height - 1 - y;
Jonathan Austin 1:8aa5cdb4ab67 163 }
Jonathan Austin 1:8aa5cdb4ab67 164
Jonathan Austin 1:8aa5cdb4ab67 165 if(rotation == MICROBIT_DISPLAY_ROTATION_270)
Jonathan Austin 1:8aa5cdb4ab67 166 {
Jonathan Austin 1:8aa5cdb4ab67 167 x = y;
Jonathan Austin 1:8aa5cdb4ab67 168 y = height - 1 - t;
Jonathan Austin 1:8aa5cdb4ab67 169 }
Jonathan Austin 1:8aa5cdb4ab67 170
Jonathan Austin 1:8aa5cdb4ab67 171 if(image.getBitmap()[y*(width*2)+x])
Jonathan Austin 1:8aa5cdb4ab67 172 col_data |= (1 << i);
Jonathan Austin 1:8aa5cdb4ab67 173 }
Jonathan Austin 1:8aa5cdb4ab67 174
Jonathan Austin 1:8aa5cdb4ab67 175 // Invert column bits (as we're sinking not sourcing power), and mask off any unused bits.
Jonathan Austin 1:8aa5cdb4ab67 176 col_data = ~col_data << matrixMap.columnStart & col_mask;
Jonathan Austin 1:8aa5cdb4ab67 177
Jonathan Austin 1:8aa5cdb4ab67 178 // Write the new bit pattern
Jonathan Austin 1:8aa5cdb4ab67 179 *LEDMatrix = col_data | row_data;
Jonathan Austin 1:8aa5cdb4ab67 180
Jonathan Austin 1:8aa5cdb4ab67 181 //timer does not have enough resolution for brightness of 1. 23.53 us
Jonathan Austin 1:8aa5cdb4ab67 182 if(brightness != MICROBIT_DISPLAY_MAXIMUM_BRIGHTNESS && brightness > MICROBIT_DISPLAY_MINIMUM_BRIGHTNESS)
Jonathan Austin 1:8aa5cdb4ab67 183 renderTimer.attach_us(this, &MicroBitDisplay::renderFinish, (((brightness * 950) / (MICROBIT_DISPLAY_MAXIMUM_BRIGHTNESS)) * system_timer_get_period()));
Jonathan Austin 1:8aa5cdb4ab67 184
Jonathan Austin 1:8aa5cdb4ab67 185 //this will take around 23us to execute
Jonathan Austin 1:8aa5cdb4ab67 186 if(brightness <= MICROBIT_DISPLAY_MINIMUM_BRIGHTNESS)
Jonathan Austin 1:8aa5cdb4ab67 187 renderFinish();
Jonathan Austin 1:8aa5cdb4ab67 188 }
Jonathan Austin 1:8aa5cdb4ab67 189
Jonathan Austin 1:8aa5cdb4ab67 190 void MicroBitDisplay::renderWithLightSense()
Jonathan Austin 1:8aa5cdb4ab67 191 {
Jonathan Austin 1:8aa5cdb4ab67 192 //reset the row counts and bit mask when we have hit the max.
Jonathan Austin 1:8aa5cdb4ab67 193 if(strobeRow == matrixMap.rows + 1)
Jonathan Austin 1:8aa5cdb4ab67 194 {
Jonathan Austin 1:8aa5cdb4ab67 195 MicroBitEvent(id, MICROBIT_DISPLAY_EVT_LIGHT_SENSE);
Jonathan Austin 1:8aa5cdb4ab67 196 strobeRow = 0;
Jonathan Austin 1:8aa5cdb4ab67 197 }
Jonathan Austin 1:8aa5cdb4ab67 198 else
Jonathan Austin 1:8aa5cdb4ab67 199 {
Jonathan Austin 1:8aa5cdb4ab67 200 render();
Jonathan Austin 1:8aa5cdb4ab67 201 this->animationUpdate();
Jonathan Austin 1:8aa5cdb4ab67 202
Jonathan Austin 1:8aa5cdb4ab67 203 // Move on to the next row.
Jonathan Austin 1:8aa5cdb4ab67 204 strobeRow++;
Jonathan Austin 1:8aa5cdb4ab67 205 }
Jonathan Austin 1:8aa5cdb4ab67 206
Jonathan Austin 1:8aa5cdb4ab67 207 }
Jonathan Austin 1:8aa5cdb4ab67 208
Jonathan Austin 1:8aa5cdb4ab67 209 void MicroBitDisplay::renderGreyscale()
Jonathan Austin 1:8aa5cdb4ab67 210 {
Jonathan Austin 1:8aa5cdb4ab67 211 uint32_t row_data = 0x01 << (microbitMatrixMap.rowStart + strobeRow);
Jonathan Austin 1:8aa5cdb4ab67 212 uint32_t col_data = 0;
Jonathan Austin 1:8aa5cdb4ab67 213
Jonathan Austin 1:8aa5cdb4ab67 214 // Calculate the bitpattern to write.
Jonathan Austin 1:8aa5cdb4ab67 215 for (int i = 0; i < matrixMap.columns; i++)
Jonathan Austin 1:8aa5cdb4ab67 216 {
Jonathan Austin 1:8aa5cdb4ab67 217 int index = (i * matrixMap.rows) + strobeRow;
Jonathan Austin 1:8aa5cdb4ab67 218
Jonathan Austin 1:8aa5cdb4ab67 219 int x = matrixMap.map[index].x;
Jonathan Austin 1:8aa5cdb4ab67 220 int y = matrixMap.map[index].y;
Jonathan Austin 1:8aa5cdb4ab67 221 int t = x;
Jonathan Austin 1:8aa5cdb4ab67 222
Jonathan Austin 1:8aa5cdb4ab67 223 if(rotation == MICROBIT_DISPLAY_ROTATION_90)
Jonathan Austin 1:8aa5cdb4ab67 224 {
Jonathan Austin 1:8aa5cdb4ab67 225 x = width - 1 - y;
Jonathan Austin 1:8aa5cdb4ab67 226 y = t;
Jonathan Austin 1:8aa5cdb4ab67 227 }
Jonathan Austin 1:8aa5cdb4ab67 228
Jonathan Austin 1:8aa5cdb4ab67 229 if(rotation == MICROBIT_DISPLAY_ROTATION_180)
Jonathan Austin 1:8aa5cdb4ab67 230 {
Jonathan Austin 1:8aa5cdb4ab67 231 x = width - 1 - x;
Jonathan Austin 1:8aa5cdb4ab67 232 y = height - 1 - y;
Jonathan Austin 1:8aa5cdb4ab67 233 }
Jonathan Austin 1:8aa5cdb4ab67 234
Jonathan Austin 1:8aa5cdb4ab67 235 if(rotation == MICROBIT_DISPLAY_ROTATION_270)
Jonathan Austin 1:8aa5cdb4ab67 236 {
Jonathan Austin 1:8aa5cdb4ab67 237 x = y;
Jonathan Austin 1:8aa5cdb4ab67 238 y = height - 1 - t;
Jonathan Austin 1:8aa5cdb4ab67 239 }
Jonathan Austin 1:8aa5cdb4ab67 240
Jonathan Austin 1:8aa5cdb4ab67 241 if(min(image.getBitmap()[y * (width * 2) + x],brightness) & greyscaleBitMsk)
Jonathan Austin 1:8aa5cdb4ab67 242 col_data |= (1 << i);
Jonathan Austin 1:8aa5cdb4ab67 243 }
Jonathan Austin 1:8aa5cdb4ab67 244
Jonathan Austin 1:8aa5cdb4ab67 245 // Invert column bits (as we're sinking not sourcing power), and mask off any unused bits.
Jonathan Austin 1:8aa5cdb4ab67 246 col_data = ~col_data << matrixMap.columnStart & col_mask;
Jonathan Austin 1:8aa5cdb4ab67 247
Jonathan Austin 1:8aa5cdb4ab67 248 // Write the new bit pattern
Jonathan Austin 1:8aa5cdb4ab67 249 *LEDMatrix = col_data | row_data;
Jonathan Austin 1:8aa5cdb4ab67 250
Jonathan Austin 1:8aa5cdb4ab67 251 if(timingCount > MICROBIT_DISPLAY_GREYSCALE_BIT_DEPTH-1)
Jonathan Austin 1:8aa5cdb4ab67 252 return;
Jonathan Austin 1:8aa5cdb4ab67 253
Jonathan Austin 1:8aa5cdb4ab67 254 greyscaleBitMsk <<= 1;
Jonathan Austin 1:8aa5cdb4ab67 255
Jonathan Austin 1:8aa5cdb4ab67 256 if(timingCount < 3)
Jonathan Austin 1:8aa5cdb4ab67 257 {
Jonathan Austin 1:8aa5cdb4ab67 258 wait_us(greyScaleTimings[timingCount++]);
Jonathan Austin 1:8aa5cdb4ab67 259 renderGreyscale();
Jonathan Austin 1:8aa5cdb4ab67 260 return;
Jonathan Austin 1:8aa5cdb4ab67 261 }
Jonathan Austin 1:8aa5cdb4ab67 262 renderTimer.attach_us(this,&MicroBitDisplay::renderGreyscale, greyScaleTimings[timingCount++]);
Jonathan Austin 1:8aa5cdb4ab67 263 }
Jonathan Austin 1:8aa5cdb4ab67 264
Jonathan Austin 1:8aa5cdb4ab67 265 /**
Jonathan Austin 1:8aa5cdb4ab67 266 * Periodic callback, that we use to perform any animations we have running.
Jonathan Austin 1:8aa5cdb4ab67 267 */
Jonathan Austin 1:8aa5cdb4ab67 268 void
Jonathan Austin 1:8aa5cdb4ab67 269 MicroBitDisplay::animationUpdate()
Jonathan Austin 1:8aa5cdb4ab67 270 {
Jonathan Austin 1:8aa5cdb4ab67 271 // If there's no ongoing animation, then nothing to do.
Jonathan Austin 1:8aa5cdb4ab67 272 if (animationMode == ANIMATION_MODE_NONE)
Jonathan Austin 1:8aa5cdb4ab67 273 return;
Jonathan Austin 1:8aa5cdb4ab67 274
Jonathan Austin 1:8aa5cdb4ab67 275 animationTick += system_timer_get_period();
Jonathan Austin 1:8aa5cdb4ab67 276
Jonathan Austin 1:8aa5cdb4ab67 277 if(animationTick >= animationDelay)
Jonathan Austin 1:8aa5cdb4ab67 278 {
Jonathan Austin 1:8aa5cdb4ab67 279 animationTick = 0;
Jonathan Austin 1:8aa5cdb4ab67 280
Jonathan Austin 1:8aa5cdb4ab67 281 if (animationMode == ANIMATION_MODE_SCROLL_TEXT)
Jonathan Austin 1:8aa5cdb4ab67 282 this->updateScrollText();
Jonathan Austin 1:8aa5cdb4ab67 283
Jonathan Austin 1:8aa5cdb4ab67 284 if (animationMode == ANIMATION_MODE_PRINT_TEXT)
Jonathan Austin 1:8aa5cdb4ab67 285 this->updatePrintText();
Jonathan Austin 1:8aa5cdb4ab67 286
Jonathan Austin 1:8aa5cdb4ab67 287 if (animationMode == ANIMATION_MODE_SCROLL_IMAGE)
Jonathan Austin 1:8aa5cdb4ab67 288 this->updateScrollImage();
Jonathan Austin 1:8aa5cdb4ab67 289
Jonathan Austin 1:8aa5cdb4ab67 290 if (animationMode == ANIMATION_MODE_ANIMATE_IMAGE)
Jonathan Austin 1:8aa5cdb4ab67 291 this->updateAnimateImage();
Jonathan Austin 1:8aa5cdb4ab67 292
Jonathan Austin 1:8aa5cdb4ab67 293 if(animationMode == ANIMATION_MODE_PRINT_CHARACTER)
Jonathan Austin 1:8aa5cdb4ab67 294 {
Jonathan Austin 1:8aa5cdb4ab67 295 animationMode = ANIMATION_MODE_NONE;
Jonathan Austin 1:8aa5cdb4ab67 296 this->sendAnimationCompleteEvent();
Jonathan Austin 1:8aa5cdb4ab67 297 }
Jonathan Austin 1:8aa5cdb4ab67 298 }
Jonathan Austin 1:8aa5cdb4ab67 299 }
Jonathan Austin 1:8aa5cdb4ab67 300
Jonathan Austin 1:8aa5cdb4ab67 301 /**
Jonathan Austin 1:8aa5cdb4ab67 302 * Broadcasts an event onto the defult EventModel indicating that the
Jonathan Austin 1:8aa5cdb4ab67 303 * current animation has completed.
Jonathan Austin 1:8aa5cdb4ab67 304 */
Jonathan Austin 1:8aa5cdb4ab67 305 void MicroBitDisplay::sendAnimationCompleteEvent()
Jonathan Austin 1:8aa5cdb4ab67 306 {
Jonathan Austin 1:8aa5cdb4ab67 307 // Signal that we've completed an animation.
Jonathan Austin 1:8aa5cdb4ab67 308 MicroBitEvent(id,MICROBIT_DISPLAY_EVT_ANIMATION_COMPLETE);
Jonathan Austin 1:8aa5cdb4ab67 309
Jonathan Austin 1:8aa5cdb4ab67 310 // Wake up a fiber that was blocked on the animation (if any).
Jonathan Austin 1:8aa5cdb4ab67 311 MicroBitEvent(MICROBIT_ID_NOTIFY_ONE, MICROBIT_DISPLAY_EVT_FREE);
Jonathan Austin 1:8aa5cdb4ab67 312 }
Jonathan Austin 1:8aa5cdb4ab67 313
Jonathan Austin 1:8aa5cdb4ab67 314 /**
Jonathan Austin 1:8aa5cdb4ab67 315 * Internal scrollText update method.
Jonathan Austin 1:8aa5cdb4ab67 316 * Shift the screen image by one pixel to the left. If necessary, paste in the next char.
Jonathan Austin 1:8aa5cdb4ab67 317 */
Jonathan Austin 1:8aa5cdb4ab67 318 void MicroBitDisplay::updateScrollText()
Jonathan Austin 1:8aa5cdb4ab67 319 {
Jonathan Austin 1:8aa5cdb4ab67 320 image.shiftLeft(1);
Jonathan Austin 1:8aa5cdb4ab67 321 scrollingPosition++;
Jonathan Austin 1:8aa5cdb4ab67 322
Jonathan Austin 1:8aa5cdb4ab67 323 if (scrollingPosition == width + MICROBIT_DISPLAY_SPACING)
Jonathan Austin 1:8aa5cdb4ab67 324 {
Jonathan Austin 1:8aa5cdb4ab67 325 scrollingPosition = 0;
Jonathan Austin 1:8aa5cdb4ab67 326
Jonathan Austin 1:8aa5cdb4ab67 327 image.print(scrollingChar < scrollingText.length() ? scrollingText.charAt(scrollingChar) : ' ',width,0);
Jonathan Austin 1:8aa5cdb4ab67 328
Jonathan Austin 1:8aa5cdb4ab67 329 if (scrollingChar > scrollingText.length())
Jonathan Austin 1:8aa5cdb4ab67 330 {
Jonathan Austin 1:8aa5cdb4ab67 331 animationMode = ANIMATION_MODE_NONE;
Jonathan Austin 1:8aa5cdb4ab67 332 this->sendAnimationCompleteEvent();
Jonathan Austin 1:8aa5cdb4ab67 333 return;
Jonathan Austin 1:8aa5cdb4ab67 334 }
Jonathan Austin 1:8aa5cdb4ab67 335 scrollingChar++;
Jonathan Austin 1:8aa5cdb4ab67 336 }
Jonathan Austin 1:8aa5cdb4ab67 337 }
Jonathan Austin 1:8aa5cdb4ab67 338
Jonathan Austin 1:8aa5cdb4ab67 339 /**
Jonathan Austin 1:8aa5cdb4ab67 340 * Internal printText update method.
Jonathan Austin 1:8aa5cdb4ab67 341 * Paste the next character in the string.
Jonathan Austin 1:8aa5cdb4ab67 342 */
Jonathan Austin 1:8aa5cdb4ab67 343 void MicroBitDisplay::updatePrintText()
Jonathan Austin 1:8aa5cdb4ab67 344 {
Jonathan Austin 1:8aa5cdb4ab67 345 image.print(printingChar < printingText.length() ? printingText.charAt(printingChar) : ' ',0,0);
Jonathan Austin 1:8aa5cdb4ab67 346
Jonathan Austin 1:8aa5cdb4ab67 347 if (printingChar > printingText.length())
Jonathan Austin 1:8aa5cdb4ab67 348 {
Jonathan Austin 1:8aa5cdb4ab67 349 animationMode = ANIMATION_MODE_NONE;
Jonathan Austin 1:8aa5cdb4ab67 350
Jonathan Austin 1:8aa5cdb4ab67 351 this->sendAnimationCompleteEvent();
Jonathan Austin 1:8aa5cdb4ab67 352 return;
Jonathan Austin 1:8aa5cdb4ab67 353 }
Jonathan Austin 1:8aa5cdb4ab67 354
Jonathan Austin 1:8aa5cdb4ab67 355 printingChar++;
Jonathan Austin 1:8aa5cdb4ab67 356 }
Jonathan Austin 1:8aa5cdb4ab67 357
Jonathan Austin 1:8aa5cdb4ab67 358 /**
Jonathan Austin 1:8aa5cdb4ab67 359 * Internal scrollImage update method.
Jonathan Austin 1:8aa5cdb4ab67 360 * Paste the stored bitmap at the appropriate point.
Jonathan Austin 1:8aa5cdb4ab67 361 */
Jonathan Austin 1:8aa5cdb4ab67 362 void MicroBitDisplay::updateScrollImage()
Jonathan Austin 1:8aa5cdb4ab67 363 {
Jonathan Austin 1:8aa5cdb4ab67 364 image.clear();
Jonathan Austin 1:8aa5cdb4ab67 365
Jonathan Austin 1:8aa5cdb4ab67 366 if (((image.paste(scrollingImage, scrollingImagePosition, 0, 0) == 0) && scrollingImageRendered) || scrollingImageStride == 0)
Jonathan Austin 1:8aa5cdb4ab67 367 {
Jonathan Austin 1:8aa5cdb4ab67 368 animationMode = ANIMATION_MODE_NONE;
Jonathan Austin 1:8aa5cdb4ab67 369 this->sendAnimationCompleteEvent();
Jonathan Austin 1:8aa5cdb4ab67 370
Jonathan Austin 1:8aa5cdb4ab67 371 return;
Jonathan Austin 1:8aa5cdb4ab67 372 }
Jonathan Austin 1:8aa5cdb4ab67 373
Jonathan Austin 1:8aa5cdb4ab67 374 scrollingImagePosition += scrollingImageStride;
Jonathan Austin 1:8aa5cdb4ab67 375 scrollingImageRendered = true;
Jonathan Austin 1:8aa5cdb4ab67 376 }
Jonathan Austin 1:8aa5cdb4ab67 377
Jonathan Austin 1:8aa5cdb4ab67 378 /**
Jonathan Austin 1:8aa5cdb4ab67 379 * Internal animateImage update method.
Jonathan Austin 1:8aa5cdb4ab67 380 * Paste the stored bitmap at the appropriate point and stop on the last frame.
Jonathan Austin 1:8aa5cdb4ab67 381 */
Jonathan Austin 1:8aa5cdb4ab67 382 void MicroBitDisplay::updateAnimateImage()
Jonathan Austin 1:8aa5cdb4ab67 383 {
Jonathan Austin 1:8aa5cdb4ab67 384 //wait until we have rendered the last position to give a continuous animation.
Jonathan Austin 1:8aa5cdb4ab67 385 if (scrollingImagePosition <= -scrollingImage.getWidth() + (MICROBIT_DISPLAY_WIDTH + scrollingImageStride) && scrollingImageRendered)
Jonathan Austin 1:8aa5cdb4ab67 386 {
Jonathan Austin 1:8aa5cdb4ab67 387 animationMode = ANIMATION_MODE_NONE;
Jonathan Austin 1:8aa5cdb4ab67 388 this->clear();
Jonathan Austin 1:8aa5cdb4ab67 389 this->sendAnimationCompleteEvent();
Jonathan Austin 1:8aa5cdb4ab67 390 return;
Jonathan Austin 1:8aa5cdb4ab67 391 }
Jonathan Austin 1:8aa5cdb4ab67 392
Jonathan Austin 1:8aa5cdb4ab67 393 if(scrollingImagePosition > 0)
Jonathan Austin 1:8aa5cdb4ab67 394 image.shiftLeft(-scrollingImageStride);
Jonathan Austin 1:8aa5cdb4ab67 395
Jonathan Austin 1:8aa5cdb4ab67 396 image.paste(scrollingImage, scrollingImagePosition, 0, 0);
Jonathan Austin 1:8aa5cdb4ab67 397
Jonathan Austin 1:8aa5cdb4ab67 398 if(scrollingImageStride == 0)
Jonathan Austin 1:8aa5cdb4ab67 399 {
Jonathan Austin 1:8aa5cdb4ab67 400 animationMode = ANIMATION_MODE_NONE;
Jonathan Austin 1:8aa5cdb4ab67 401 this->sendAnimationCompleteEvent();
Jonathan Austin 1:8aa5cdb4ab67 402 }
Jonathan Austin 1:8aa5cdb4ab67 403
Jonathan Austin 1:8aa5cdb4ab67 404 scrollingImageRendered = true;
Jonathan Austin 1:8aa5cdb4ab67 405
Jonathan Austin 1:8aa5cdb4ab67 406 scrollingImagePosition += scrollingImageStride;
Jonathan Austin 1:8aa5cdb4ab67 407 }
Jonathan Austin 1:8aa5cdb4ab67 408
Jonathan Austin 1:8aa5cdb4ab67 409 /**
Jonathan Austin 1:8aa5cdb4ab67 410 * Resets the current given animation.
Jonathan Austin 1:8aa5cdb4ab67 411 */
Jonathan Austin 1:8aa5cdb4ab67 412 void MicroBitDisplay::stopAnimation()
Jonathan Austin 1:8aa5cdb4ab67 413 {
Jonathan Austin 1:8aa5cdb4ab67 414 // Reset any ongoing animation.
Jonathan Austin 1:8aa5cdb4ab67 415 if (animationMode != ANIMATION_MODE_NONE)
Jonathan Austin 1:8aa5cdb4ab67 416 {
Jonathan Austin 1:8aa5cdb4ab67 417 animationMode = ANIMATION_MODE_NONE;
Jonathan Austin 1:8aa5cdb4ab67 418
Jonathan Austin 1:8aa5cdb4ab67 419 // Indicate that we've completed an animation.
Jonathan Austin 1:8aa5cdb4ab67 420 MicroBitEvent(id,MICROBIT_DISPLAY_EVT_ANIMATION_COMPLETE);
Jonathan Austin 1:8aa5cdb4ab67 421
Jonathan Austin 1:8aa5cdb4ab67 422 // Wake up aall fibers that may blocked on the animation (if any).
Jonathan Austin 1:8aa5cdb4ab67 423 MicroBitEvent(MICROBIT_ID_NOTIFY, MICROBIT_DISPLAY_EVT_FREE);
Jonathan Austin 1:8aa5cdb4ab67 424 }
Jonathan Austin 1:8aa5cdb4ab67 425
Jonathan Austin 1:8aa5cdb4ab67 426 // Clear the display and setup the animation timers.
Jonathan Austin 1:8aa5cdb4ab67 427 this->image.clear();
Jonathan Austin 1:8aa5cdb4ab67 428 }
Jonathan Austin 1:8aa5cdb4ab67 429
Jonathan Austin 1:8aa5cdb4ab67 430 /**
Jonathan Austin 1:8aa5cdb4ab67 431 * Blocks the current fiber until the display is available (i.e. does not effect is being displayed).
Jonathan Austin 1:8aa5cdb4ab67 432 * Animations are queued until their time to display.
Jonathan Austin 1:8aa5cdb4ab67 433 */
Jonathan Austin 1:8aa5cdb4ab67 434 void MicroBitDisplay::waitForFreeDisplay()
Jonathan Austin 1:8aa5cdb4ab67 435 {
Jonathan Austin 1:8aa5cdb4ab67 436 // If there's an ongoing animation, wait for our turn to display.
Jonathan Austin 1:8aa5cdb4ab67 437 if (animationMode != ANIMATION_MODE_NONE && animationMode != ANIMATION_MODE_STOPPED)
Jonathan Austin 1:8aa5cdb4ab67 438 fiber_wait_for_event(MICROBIT_ID_NOTIFY, MICROBIT_DISPLAY_EVT_FREE);
Jonathan Austin 1:8aa5cdb4ab67 439 }
Jonathan Austin 1:8aa5cdb4ab67 440
Jonathan Austin 1:8aa5cdb4ab67 441 /**
Jonathan Austin 1:8aa5cdb4ab67 442 * Blocks the current fiber until the current animation has finished.
Jonathan Austin 1:8aa5cdb4ab67 443 * If the scheduler is not running, this call will essentially perform a spinning wait.
Jonathan Austin 1:8aa5cdb4ab67 444 */
Jonathan Austin 1:8aa5cdb4ab67 445 void MicroBitDisplay::fiberWait()
Jonathan Austin 1:8aa5cdb4ab67 446 {
Jonathan Austin 1:8aa5cdb4ab67 447 if (fiber_wait_for_event(MICROBIT_ID_DISPLAY, MICROBIT_DISPLAY_EVT_ANIMATION_COMPLETE) == MICROBIT_NOT_SUPPORTED)
Jonathan Austin 1:8aa5cdb4ab67 448 while(animationMode != ANIMATION_MODE_NONE && animationMode != ANIMATION_MODE_STOPPED)
Jonathan Austin 1:8aa5cdb4ab67 449 __WFE();
Jonathan Austin 1:8aa5cdb4ab67 450 }
Jonathan Austin 1:8aa5cdb4ab67 451
Jonathan Austin 1:8aa5cdb4ab67 452 /**
Jonathan Austin 1:8aa5cdb4ab67 453 * Prints the given character to the display, if it is not in use.
Jonathan Austin 1:8aa5cdb4ab67 454 *
Jonathan Austin 1:8aa5cdb4ab67 455 * @param c The character to display.
Jonathan Austin 1:8aa5cdb4ab67 456 *
Jonathan Austin 1:8aa5cdb4ab67 457 * @param delay Optional parameter - the time for which to show the character. Zero displays the character forever,
Jonathan Austin 1:8aa5cdb4ab67 458 * or until the Displays next use.
Jonathan Austin 1:8aa5cdb4ab67 459 *
Jonathan Austin 1:8aa5cdb4ab67 460 * @return MICROBIT_OK, MICROBIT_BUSY is the screen is in use, or MICROBIT_INVALID_PARAMETER.
Jonathan Austin 1:8aa5cdb4ab67 461 *
Jonathan Austin 1:8aa5cdb4ab67 462 * @code
Jonathan Austin 1:8aa5cdb4ab67 463 * display.printAsync('p');
Jonathan Austin 1:8aa5cdb4ab67 464 * display.printAsync('p',100);
Jonathan Austin 1:8aa5cdb4ab67 465 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 466 */
Jonathan Austin 1:8aa5cdb4ab67 467 int MicroBitDisplay::printCharAsync(char c, int delay)
Jonathan Austin 1:8aa5cdb4ab67 468 {
Jonathan Austin 1:8aa5cdb4ab67 469 //sanitise this value
Jonathan Austin 1:8aa5cdb4ab67 470 if(delay < 0)
Jonathan Austin 1:8aa5cdb4ab67 471 return MICROBIT_INVALID_PARAMETER;
Jonathan Austin 1:8aa5cdb4ab67 472
Jonathan Austin 1:8aa5cdb4ab67 473 // If the display is free, it's our turn to display.
Jonathan Austin 1:8aa5cdb4ab67 474 if (animationMode == ANIMATION_MODE_NONE || animationMode == ANIMATION_MODE_STOPPED)
Jonathan Austin 1:8aa5cdb4ab67 475 {
Jonathan Austin 1:8aa5cdb4ab67 476 image.print(c, 0, 0);
Jonathan Austin 1:8aa5cdb4ab67 477
Jonathan Austin 1:8aa5cdb4ab67 478 if (delay > 0)
Jonathan Austin 1:8aa5cdb4ab67 479 {
Jonathan Austin 1:8aa5cdb4ab67 480 animationDelay = delay;
Jonathan Austin 1:8aa5cdb4ab67 481 animationTick = 0;
Jonathan Austin 1:8aa5cdb4ab67 482 animationMode = ANIMATION_MODE_PRINT_CHARACTER;
Jonathan Austin 1:8aa5cdb4ab67 483 }
Jonathan Austin 1:8aa5cdb4ab67 484 }
Jonathan Austin 1:8aa5cdb4ab67 485 else
Jonathan Austin 1:8aa5cdb4ab67 486 {
Jonathan Austin 1:8aa5cdb4ab67 487 return MICROBIT_BUSY;
Jonathan Austin 1:8aa5cdb4ab67 488 }
Jonathan Austin 1:8aa5cdb4ab67 489
Jonathan Austin 1:8aa5cdb4ab67 490 return MICROBIT_OK;
Jonathan Austin 1:8aa5cdb4ab67 491 }
Jonathan Austin 1:8aa5cdb4ab67 492
Jonathan Austin 1:8aa5cdb4ab67 493 /**
Jonathan Austin 1:8aa5cdb4ab67 494 * Prints the given ManagedString to the display, one character at a time.
Jonathan Austin 1:8aa5cdb4ab67 495 * Returns immediately, and executes the animation asynchronously.
Jonathan Austin 1:8aa5cdb4ab67 496 *
Jonathan Austin 1:8aa5cdb4ab67 497 * @param s The string to display.
Jonathan Austin 1:8aa5cdb4ab67 498 *
Jonathan Austin 1:8aa5cdb4ab67 499 * @param delay The time to delay between characters, in milliseconds. Must be > 0.
Jonathan Austin 1:8aa5cdb4ab67 500 * Defaults to: MICROBIT_DEFAULT_PRINT_SPEED.
Jonathan Austin 1:8aa5cdb4ab67 501 *
Jonathan Austin 1:8aa5cdb4ab67 502 * @return MICROBIT_OK, or MICROBIT_INVALID_PARAMETER.
Jonathan Austin 1:8aa5cdb4ab67 503 *
Jonathan Austin 1:8aa5cdb4ab67 504 * @code
Jonathan Austin 1:8aa5cdb4ab67 505 * display.printAsync("abc123",400);
Jonathan Austin 1:8aa5cdb4ab67 506 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 507 */
Jonathan Austin 1:8aa5cdb4ab67 508 int MicroBitDisplay::printAsync(ManagedString s, int delay)
Jonathan Austin 1:8aa5cdb4ab67 509 {
Jonathan Austin 1:8aa5cdb4ab67 510 if (s.length() == 1)
Jonathan Austin 1:8aa5cdb4ab67 511 return printCharAsync(s.charAt(0));
Jonathan Austin 1:8aa5cdb4ab67 512
Jonathan Austin 1:8aa5cdb4ab67 513 //sanitise this value
Jonathan Austin 1:8aa5cdb4ab67 514 if (delay <= 0 )
Jonathan Austin 1:8aa5cdb4ab67 515 return MICROBIT_INVALID_PARAMETER;
Jonathan Austin 1:8aa5cdb4ab67 516
Jonathan Austin 1:8aa5cdb4ab67 517 if (animationMode == ANIMATION_MODE_NONE || animationMode == ANIMATION_MODE_STOPPED)
Jonathan Austin 1:8aa5cdb4ab67 518 {
Jonathan Austin 1:8aa5cdb4ab67 519 printingChar = 0;
Jonathan Austin 1:8aa5cdb4ab67 520 printingText = s;
Jonathan Austin 1:8aa5cdb4ab67 521 animationDelay = delay;
Jonathan Austin 1:8aa5cdb4ab67 522 animationTick = 0;
Jonathan Austin 1:8aa5cdb4ab67 523
Jonathan Austin 1:8aa5cdb4ab67 524 animationMode = ANIMATION_MODE_PRINT_TEXT;
Jonathan Austin 1:8aa5cdb4ab67 525 }
Jonathan Austin 1:8aa5cdb4ab67 526 else
Jonathan Austin 1:8aa5cdb4ab67 527 {
Jonathan Austin 1:8aa5cdb4ab67 528 return MICROBIT_BUSY;
Jonathan Austin 1:8aa5cdb4ab67 529 }
Jonathan Austin 1:8aa5cdb4ab67 530
Jonathan Austin 1:8aa5cdb4ab67 531 return MICROBIT_OK;
Jonathan Austin 1:8aa5cdb4ab67 532 }
Jonathan Austin 1:8aa5cdb4ab67 533
Jonathan Austin 1:8aa5cdb4ab67 534 /**
Jonathan Austin 1:8aa5cdb4ab67 535 * Prints the given image to the display, if the display is not in use.
Jonathan Austin 1:8aa5cdb4ab67 536 * Returns immediately, and executes the animation asynchronously.
Jonathan Austin 1:8aa5cdb4ab67 537 *
Jonathan Austin 1:8aa5cdb4ab67 538 * @param i The image to display.
Jonathan Austin 1:8aa5cdb4ab67 539 *
Jonathan Austin 1:8aa5cdb4ab67 540 * @param x The horizontal position on the screen to display the image. Defaults to 0.
Jonathan Austin 1:8aa5cdb4ab67 541 *
Jonathan Austin 1:8aa5cdb4ab67 542 * @param y The vertical position on the screen to display the image. Defaults to 0.
Jonathan Austin 1:8aa5cdb4ab67 543 *
Jonathan Austin 1:8aa5cdb4ab67 544 * @param alpha Treats the brightness level '0' as transparent. Defaults to 0.
Jonathan Austin 1:8aa5cdb4ab67 545 *
Jonathan Austin 1:8aa5cdb4ab67 546 * @param delay The time to delay between characters, in milliseconds. Defaults to 0.
Jonathan Austin 1:8aa5cdb4ab67 547 *
Jonathan Austin 1:8aa5cdb4ab67 548 * @code
Jonathan Austin 1:8aa5cdb4ab67 549 * MicrobitImage i("1,1,1,1,1\n1,1,1,1,1\n");
Jonathan Austin 1:8aa5cdb4ab67 550 * display.print(i,400);
Jonathan Austin 1:8aa5cdb4ab67 551 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 552 */
Jonathan Austin 1:8aa5cdb4ab67 553 int MicroBitDisplay::printAsync(MicroBitImage i, int x, int y, int alpha, int delay)
Jonathan Austin 1:8aa5cdb4ab67 554 {
Jonathan Austin 1:8aa5cdb4ab67 555 if(delay < 0)
Jonathan Austin 1:8aa5cdb4ab67 556 return MICROBIT_INVALID_PARAMETER;
Jonathan Austin 1:8aa5cdb4ab67 557
Jonathan Austin 1:8aa5cdb4ab67 558 if (animationMode == ANIMATION_MODE_NONE || animationMode == ANIMATION_MODE_STOPPED)
Jonathan Austin 1:8aa5cdb4ab67 559 {
Jonathan Austin 1:8aa5cdb4ab67 560 image.paste(i, x, y, alpha);
Jonathan Austin 1:8aa5cdb4ab67 561
Jonathan Austin 1:8aa5cdb4ab67 562 if(delay > 0)
Jonathan Austin 1:8aa5cdb4ab67 563 {
Jonathan Austin 1:8aa5cdb4ab67 564 animationDelay = delay;
Jonathan Austin 1:8aa5cdb4ab67 565 animationTick = 0;
Jonathan Austin 1:8aa5cdb4ab67 566 animationMode = ANIMATION_MODE_PRINT_CHARACTER;
Jonathan Austin 1:8aa5cdb4ab67 567 }
Jonathan Austin 1:8aa5cdb4ab67 568 }
Jonathan Austin 1:8aa5cdb4ab67 569 else
Jonathan Austin 1:8aa5cdb4ab67 570 {
Jonathan Austin 1:8aa5cdb4ab67 571 return MICROBIT_BUSY;
Jonathan Austin 1:8aa5cdb4ab67 572 }
Jonathan Austin 1:8aa5cdb4ab67 573
Jonathan Austin 1:8aa5cdb4ab67 574 return MICROBIT_OK;
Jonathan Austin 1:8aa5cdb4ab67 575 }
Jonathan Austin 1:8aa5cdb4ab67 576
Jonathan Austin 1:8aa5cdb4ab67 577 /**
Jonathan Austin 1:8aa5cdb4ab67 578 * Prints the given character to the display.
Jonathan Austin 1:8aa5cdb4ab67 579 *
Jonathan Austin 1:8aa5cdb4ab67 580 * @param c The character to display.
Jonathan Austin 1:8aa5cdb4ab67 581 *
Jonathan Austin 1:8aa5cdb4ab67 582 * @param delay Optional parameter - the time for which to show the character. Zero displays the character forever,
Jonathan Austin 1:8aa5cdb4ab67 583 * or until the Displays next use.
Jonathan Austin 1:8aa5cdb4ab67 584 *
Jonathan Austin 1:8aa5cdb4ab67 585 * @return MICROBIT_OK, MICROBIT_CANCELLED or MICROBIT_INVALID_PARAMETER.
Jonathan Austin 1:8aa5cdb4ab67 586 *
Jonathan Austin 1:8aa5cdb4ab67 587 * @code
Jonathan Austin 1:8aa5cdb4ab67 588 * display.printAsync('p');
Jonathan Austin 1:8aa5cdb4ab67 589 * display.printAsync('p',100);
Jonathan Austin 1:8aa5cdb4ab67 590 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 591 */
Jonathan Austin 1:8aa5cdb4ab67 592 int MicroBitDisplay::printChar(char c, int delay)
Jonathan Austin 1:8aa5cdb4ab67 593 {
Jonathan Austin 1:8aa5cdb4ab67 594 if (delay < 0)
Jonathan Austin 1:8aa5cdb4ab67 595 return MICROBIT_INVALID_PARAMETER;
Jonathan Austin 1:8aa5cdb4ab67 596
Jonathan Austin 1:8aa5cdb4ab67 597 // If there's an ongoing animation, wait for our turn to display.
Jonathan Austin 1:8aa5cdb4ab67 598 this->waitForFreeDisplay();
Jonathan Austin 1:8aa5cdb4ab67 599
Jonathan Austin 1:8aa5cdb4ab67 600 // If the display is free, it's our turn to display.
Jonathan Austin 1:8aa5cdb4ab67 601 // If someone called stopAnimation(), then we simply skip...
Jonathan Austin 1:8aa5cdb4ab67 602 if (animationMode == ANIMATION_MODE_NONE)
Jonathan Austin 1:8aa5cdb4ab67 603 {
Jonathan Austin 1:8aa5cdb4ab67 604 this->printCharAsync(c, delay);
Jonathan Austin 1:8aa5cdb4ab67 605
Jonathan Austin 1:8aa5cdb4ab67 606 if (delay > 0)
Jonathan Austin 1:8aa5cdb4ab67 607 fiberWait();
Jonathan Austin 1:8aa5cdb4ab67 608 }
Jonathan Austin 1:8aa5cdb4ab67 609 else
Jonathan Austin 1:8aa5cdb4ab67 610 {
Jonathan Austin 1:8aa5cdb4ab67 611 return MICROBIT_CANCELLED;
Jonathan Austin 1:8aa5cdb4ab67 612 }
Jonathan Austin 1:8aa5cdb4ab67 613
Jonathan Austin 1:8aa5cdb4ab67 614 return MICROBIT_OK;
Jonathan Austin 1:8aa5cdb4ab67 615 }
Jonathan Austin 1:8aa5cdb4ab67 616
Jonathan Austin 1:8aa5cdb4ab67 617 /**
Jonathan Austin 1:8aa5cdb4ab67 618 * Prints the given string to the display, one character at a time.
Jonathan Austin 1:8aa5cdb4ab67 619 *
Jonathan Austin 1:8aa5cdb4ab67 620 * Blocks the calling thread until all the text has been displayed.
Jonathan Austin 1:8aa5cdb4ab67 621 *
Jonathan Austin 1:8aa5cdb4ab67 622 * @param s The string to display.
Jonathan Austin 1:8aa5cdb4ab67 623 *
Jonathan Austin 1:8aa5cdb4ab67 624 * @param delay The time to delay between characters, in milliseconds. Defaults
Jonathan Austin 1:8aa5cdb4ab67 625 * to: MICROBIT_DEFAULT_PRINT_SPEED.
Jonathan Austin 1:8aa5cdb4ab67 626 *
Jonathan Austin 1:8aa5cdb4ab67 627 * @return MICROBIT_OK, MICROBIT_CANCELLED or MICROBIT_INVALID_PARAMETER.
Jonathan Austin 1:8aa5cdb4ab67 628 *
Jonathan Austin 1:8aa5cdb4ab67 629 * @code
Jonathan Austin 1:8aa5cdb4ab67 630 * display.print("abc123",400);
Jonathan Austin 1:8aa5cdb4ab67 631 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 632 */
Jonathan Austin 1:8aa5cdb4ab67 633 int MicroBitDisplay::print(ManagedString s, int delay)
Jonathan Austin 1:8aa5cdb4ab67 634 {
Jonathan Austin 1:8aa5cdb4ab67 635 //sanitise this value
Jonathan Austin 1:8aa5cdb4ab67 636 if(delay <= 0 )
Jonathan Austin 1:8aa5cdb4ab67 637 return MICROBIT_INVALID_PARAMETER;
Jonathan Austin 1:8aa5cdb4ab67 638
Jonathan Austin 1:8aa5cdb4ab67 639 // If there's an ongoing animation, wait for our turn to display.
Jonathan Austin 1:8aa5cdb4ab67 640 this->waitForFreeDisplay();
Jonathan Austin 1:8aa5cdb4ab67 641
Jonathan Austin 1:8aa5cdb4ab67 642 // If the display is free, it's our turn to display.
Jonathan Austin 1:8aa5cdb4ab67 643 // If someone called stopAnimation(), then we simply skip...
Jonathan Austin 1:8aa5cdb4ab67 644 if (animationMode == ANIMATION_MODE_NONE)
Jonathan Austin 1:8aa5cdb4ab67 645 {
Jonathan Austin 1:8aa5cdb4ab67 646 if (s.length() == 1)
Jonathan Austin 1:8aa5cdb4ab67 647 {
Jonathan Austin 1:8aa5cdb4ab67 648 return printCharAsync(s.charAt(0));
Jonathan Austin 1:8aa5cdb4ab67 649 }
Jonathan Austin 1:8aa5cdb4ab67 650 else
Jonathan Austin 1:8aa5cdb4ab67 651 {
Jonathan Austin 1:8aa5cdb4ab67 652 this->printAsync(s, delay);
Jonathan Austin 1:8aa5cdb4ab67 653 fiberWait();
Jonathan Austin 1:8aa5cdb4ab67 654 }
Jonathan Austin 1:8aa5cdb4ab67 655 }
Jonathan Austin 1:8aa5cdb4ab67 656 else
Jonathan Austin 1:8aa5cdb4ab67 657 {
Jonathan Austin 1:8aa5cdb4ab67 658 return MICROBIT_CANCELLED;
Jonathan Austin 1:8aa5cdb4ab67 659 }
Jonathan Austin 1:8aa5cdb4ab67 660
Jonathan Austin 1:8aa5cdb4ab67 661 return MICROBIT_OK;
Jonathan Austin 1:8aa5cdb4ab67 662 }
Jonathan Austin 1:8aa5cdb4ab67 663
Jonathan Austin 1:8aa5cdb4ab67 664 /**
Jonathan Austin 1:8aa5cdb4ab67 665 * Prints the given image to the display.
Jonathan Austin 1:8aa5cdb4ab67 666 * Blocks the calling thread until all the image has been displayed.
Jonathan Austin 1:8aa5cdb4ab67 667 *
Jonathan Austin 1:8aa5cdb4ab67 668 * @param i The image to display.
Jonathan Austin 1:8aa5cdb4ab67 669 *
Jonathan Austin 1:8aa5cdb4ab67 670 * @param x The horizontal position on the screen to display the image. Defaults to 0.
Jonathan Austin 1:8aa5cdb4ab67 671 *
Jonathan Austin 1:8aa5cdb4ab67 672 * @param y The vertical position on the screen to display the image. Defaults to 0.
Jonathan Austin 1:8aa5cdb4ab67 673 *
Jonathan Austin 1:8aa5cdb4ab67 674 * @param alpha Treats the brightness level '0' as transparent. Defaults to 0.
Jonathan Austin 1:8aa5cdb4ab67 675 *
Jonathan Austin 1:8aa5cdb4ab67 676 * @param delay The time to display the image for, or zero to show the image forever. Defaults to 0.
Jonathan Austin 1:8aa5cdb4ab67 677 *
Jonathan Austin 1:8aa5cdb4ab67 678 * @return MICROBIT_OK, MICROBIT_BUSY if the display is already in use, or MICROBIT_INVALID_PARAMETER.
Jonathan Austin 1:8aa5cdb4ab67 679 *
Jonathan Austin 1:8aa5cdb4ab67 680 * @code
Jonathan Austin 1:8aa5cdb4ab67 681 * MicrobitImage i("1,1,1,1,1\n1,1,1,1,1\n");
Jonathan Austin 1:8aa5cdb4ab67 682 * display.print(i,400);
Jonathan Austin 1:8aa5cdb4ab67 683 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 684 */
Jonathan Austin 1:8aa5cdb4ab67 685 int MicroBitDisplay::print(MicroBitImage i, int x, int y, int alpha, int delay)
Jonathan Austin 1:8aa5cdb4ab67 686 {
Jonathan Austin 1:8aa5cdb4ab67 687 if(delay < 0)
Jonathan Austin 1:8aa5cdb4ab67 688 return MICROBIT_INVALID_PARAMETER;
Jonathan Austin 1:8aa5cdb4ab67 689
Jonathan Austin 1:8aa5cdb4ab67 690 // If there's an ongoing animation, wait for our turn to display.
Jonathan Austin 1:8aa5cdb4ab67 691 this->waitForFreeDisplay();
Jonathan Austin 1:8aa5cdb4ab67 692
Jonathan Austin 1:8aa5cdb4ab67 693 // If the display is free, it's our turn to display.
Jonathan Austin 1:8aa5cdb4ab67 694 // If someone called stopAnimation(), then we simply skip...
Jonathan Austin 1:8aa5cdb4ab67 695 if (animationMode == ANIMATION_MODE_NONE)
Jonathan Austin 1:8aa5cdb4ab67 696 {
Jonathan Austin 1:8aa5cdb4ab67 697 this->printAsync(i, x, y, alpha, delay);
Jonathan Austin 1:8aa5cdb4ab67 698
Jonathan Austin 1:8aa5cdb4ab67 699 if (delay > 0)
Jonathan Austin 1:8aa5cdb4ab67 700 fiberWait();
Jonathan Austin 1:8aa5cdb4ab67 701 }
Jonathan Austin 1:8aa5cdb4ab67 702 else
Jonathan Austin 1:8aa5cdb4ab67 703 {
Jonathan Austin 1:8aa5cdb4ab67 704 return MICROBIT_CANCELLED;
Jonathan Austin 1:8aa5cdb4ab67 705 }
Jonathan Austin 1:8aa5cdb4ab67 706
Jonathan Austin 1:8aa5cdb4ab67 707 return MICROBIT_OK;
Jonathan Austin 1:8aa5cdb4ab67 708 }
Jonathan Austin 1:8aa5cdb4ab67 709
Jonathan Austin 1:8aa5cdb4ab67 710 /**
Jonathan Austin 1:8aa5cdb4ab67 711 * Scrolls the given string to the display, from right to left.
Jonathan Austin 1:8aa5cdb4ab67 712 * Returns immediately, and executes the animation asynchronously.
Jonathan Austin 1:8aa5cdb4ab67 713 *
Jonathan Austin 1:8aa5cdb4ab67 714 * @param s The string to display.
Jonathan Austin 1:8aa5cdb4ab67 715 *
Jonathan Austin 1:8aa5cdb4ab67 716 * @param delay The time to delay between characters, in milliseconds. Defaults
Jonathan Austin 1:8aa5cdb4ab67 717 * to: MICROBIT_DEFAULT_SCROLL_SPEED.
Jonathan Austin 1:8aa5cdb4ab67 718 *
Jonathan Austin 1:8aa5cdb4ab67 719 * @return MICROBIT_OK, MICROBIT_BUSY if the display is already in use, or MICROBIT_INVALID_PARAMETER.
Jonathan Austin 1:8aa5cdb4ab67 720 *
Jonathan Austin 1:8aa5cdb4ab67 721 * @code
Jonathan Austin 1:8aa5cdb4ab67 722 * display.scrollAsync("abc123",100);
Jonathan Austin 1:8aa5cdb4ab67 723 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 724 */
Jonathan Austin 1:8aa5cdb4ab67 725 int MicroBitDisplay::scrollAsync(ManagedString s, int delay)
Jonathan Austin 1:8aa5cdb4ab67 726 {
Jonathan Austin 1:8aa5cdb4ab67 727 //sanitise this value
Jonathan Austin 1:8aa5cdb4ab67 728 if(delay <= 0)
Jonathan Austin 1:8aa5cdb4ab67 729 return MICROBIT_INVALID_PARAMETER;
Jonathan Austin 1:8aa5cdb4ab67 730
Jonathan Austin 1:8aa5cdb4ab67 731 // If the display is free, it's our turn to display.
Jonathan Austin 1:8aa5cdb4ab67 732 if (animationMode == ANIMATION_MODE_NONE || animationMode == ANIMATION_MODE_STOPPED)
Jonathan Austin 1:8aa5cdb4ab67 733 {
Jonathan Austin 1:8aa5cdb4ab67 734 scrollingPosition = width-1;
Jonathan Austin 1:8aa5cdb4ab67 735 scrollingChar = 0;
Jonathan Austin 1:8aa5cdb4ab67 736 scrollingText = s;
Jonathan Austin 1:8aa5cdb4ab67 737
Jonathan Austin 1:8aa5cdb4ab67 738 animationDelay = delay;
Jonathan Austin 1:8aa5cdb4ab67 739 animationTick = 0;
Jonathan Austin 1:8aa5cdb4ab67 740 animationMode = ANIMATION_MODE_SCROLL_TEXT;
Jonathan Austin 1:8aa5cdb4ab67 741 }
Jonathan Austin 1:8aa5cdb4ab67 742 else
Jonathan Austin 1:8aa5cdb4ab67 743 {
Jonathan Austin 1:8aa5cdb4ab67 744 return MICROBIT_BUSY;
Jonathan Austin 1:8aa5cdb4ab67 745 }
Jonathan Austin 1:8aa5cdb4ab67 746
Jonathan Austin 1:8aa5cdb4ab67 747 return MICROBIT_OK;
Jonathan Austin 1:8aa5cdb4ab67 748 }
Jonathan Austin 1:8aa5cdb4ab67 749
Jonathan Austin 1:8aa5cdb4ab67 750 /**
Jonathan Austin 1:8aa5cdb4ab67 751 * Scrolls the given image across the display, from right to left.
Jonathan Austin 1:8aa5cdb4ab67 752 * Returns immediately, and executes the animation asynchronously.
Jonathan Austin 1:8aa5cdb4ab67 753 *
Jonathan Austin 1:8aa5cdb4ab67 754 * @param image The image to display.
Jonathan Austin 1:8aa5cdb4ab67 755 *
Jonathan Austin 1:8aa5cdb4ab67 756 * @param delay The time between updates, in milliseconds. Defaults
Jonathan Austin 1:8aa5cdb4ab67 757 * to: MICROBIT_DEFAULT_SCROLL_SPEED.
Jonathan Austin 1:8aa5cdb4ab67 758 *
Jonathan Austin 1:8aa5cdb4ab67 759 * @param stride The number of pixels to shift by in each update. Defaults to MICROBIT_DEFAULT_SCROLL_STRIDE.
Jonathan Austin 1:8aa5cdb4ab67 760 *
Jonathan Austin 1:8aa5cdb4ab67 761 * @return MICROBIT_OK, MICROBIT_BUSY if the display is already in use, or MICROBIT_INVALID_PARAMETER.
Jonathan Austin 1:8aa5cdb4ab67 762 *
Jonathan Austin 1:8aa5cdb4ab67 763 * @code
Jonathan Austin 1:8aa5cdb4ab67 764 * MicrobitImage i("1,1,1,1,1\n1,1,1,1,1\n");
Jonathan Austin 1:8aa5cdb4ab67 765 * display.scrollAsync(i,100,1);
Jonathan Austin 1:8aa5cdb4ab67 766 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 767 */
Jonathan Austin 1:8aa5cdb4ab67 768 int MicroBitDisplay::scrollAsync(MicroBitImage image, int delay, int stride)
Jonathan Austin 1:8aa5cdb4ab67 769 {
Jonathan Austin 1:8aa5cdb4ab67 770 //sanitise the delay value
Jonathan Austin 1:8aa5cdb4ab67 771 if(delay <= 0)
Jonathan Austin 1:8aa5cdb4ab67 772 return MICROBIT_INVALID_PARAMETER;
Jonathan Austin 1:8aa5cdb4ab67 773
Jonathan Austin 1:8aa5cdb4ab67 774 // If the display is free, it's our turn to display.
Jonathan Austin 1:8aa5cdb4ab67 775 if (animationMode == ANIMATION_MODE_NONE || animationMode == ANIMATION_MODE_STOPPED)
Jonathan Austin 1:8aa5cdb4ab67 776 {
Jonathan Austin 1:8aa5cdb4ab67 777 scrollingImagePosition = stride < 0 ? width : -image.getWidth();
Jonathan Austin 1:8aa5cdb4ab67 778 scrollingImageStride = stride;
Jonathan Austin 1:8aa5cdb4ab67 779 scrollingImage = image;
Jonathan Austin 1:8aa5cdb4ab67 780 scrollingImageRendered = false;
Jonathan Austin 1:8aa5cdb4ab67 781
Jonathan Austin 1:8aa5cdb4ab67 782 animationDelay = stride == 0 ? 0 : delay;
Jonathan Austin 1:8aa5cdb4ab67 783 animationTick = 0;
Jonathan Austin 1:8aa5cdb4ab67 784 animationMode = ANIMATION_MODE_SCROLL_IMAGE;
Jonathan Austin 1:8aa5cdb4ab67 785 }
Jonathan Austin 1:8aa5cdb4ab67 786 else
Jonathan Austin 1:8aa5cdb4ab67 787 {
Jonathan Austin 1:8aa5cdb4ab67 788 return MICROBIT_BUSY;
Jonathan Austin 1:8aa5cdb4ab67 789 }
Jonathan Austin 1:8aa5cdb4ab67 790
Jonathan Austin 1:8aa5cdb4ab67 791 return MICROBIT_OK;
Jonathan Austin 1:8aa5cdb4ab67 792 }
Jonathan Austin 1:8aa5cdb4ab67 793
Jonathan Austin 1:8aa5cdb4ab67 794 /**
Jonathan Austin 1:8aa5cdb4ab67 795 * Scrolls the given string across the display, from right to left.
Jonathan Austin 1:8aa5cdb4ab67 796 * Blocks the calling thread until all text has been displayed.
Jonathan Austin 1:8aa5cdb4ab67 797 *
Jonathan Austin 1:8aa5cdb4ab67 798 * @param s The string to display.
Jonathan Austin 1:8aa5cdb4ab67 799 *
Jonathan Austin 1:8aa5cdb4ab67 800 * @param delay The time to delay between characters, in milliseconds. Defaults
Jonathan Austin 1:8aa5cdb4ab67 801 * to: MICROBIT_DEFAULT_SCROLL_SPEED.
Jonathan Austin 1:8aa5cdb4ab67 802 *
Jonathan Austin 1:8aa5cdb4ab67 803 * @return MICROBIT_OK, MICROBIT_CANCELLED or MICROBIT_INVALID_PARAMETER.
Jonathan Austin 1:8aa5cdb4ab67 804 *
Jonathan Austin 1:8aa5cdb4ab67 805 * @code
Jonathan Austin 1:8aa5cdb4ab67 806 * display.scroll("abc123",100);
Jonathan Austin 1:8aa5cdb4ab67 807 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 808 */
Jonathan Austin 1:8aa5cdb4ab67 809 int MicroBitDisplay::scroll(ManagedString s, int delay)
Jonathan Austin 1:8aa5cdb4ab67 810 {
Jonathan Austin 1:8aa5cdb4ab67 811 //sanitise this value
Jonathan Austin 1:8aa5cdb4ab67 812 if(delay <= 0)
Jonathan Austin 1:8aa5cdb4ab67 813 return MICROBIT_INVALID_PARAMETER;
Jonathan Austin 1:8aa5cdb4ab67 814
Jonathan Austin 1:8aa5cdb4ab67 815 // If there's an ongoing animation, wait for our turn to display.
Jonathan Austin 1:8aa5cdb4ab67 816 this->waitForFreeDisplay();
Jonathan Austin 1:8aa5cdb4ab67 817
Jonathan Austin 1:8aa5cdb4ab67 818 // If the display is free, it's our turn to display.
Jonathan Austin 1:8aa5cdb4ab67 819 // If someone called stopAnimation(), then we simply skip...
Jonathan Austin 1:8aa5cdb4ab67 820 if (animationMode == ANIMATION_MODE_NONE)
Jonathan Austin 1:8aa5cdb4ab67 821 {
Jonathan Austin 1:8aa5cdb4ab67 822 // Start the effect.
Jonathan Austin 1:8aa5cdb4ab67 823 this->scrollAsync(s, delay);
Jonathan Austin 1:8aa5cdb4ab67 824
Jonathan Austin 1:8aa5cdb4ab67 825 // Wait for completion.
Jonathan Austin 1:8aa5cdb4ab67 826 fiberWait();
Jonathan Austin 1:8aa5cdb4ab67 827 }
Jonathan Austin 1:8aa5cdb4ab67 828 else
Jonathan Austin 1:8aa5cdb4ab67 829 {
Jonathan Austin 1:8aa5cdb4ab67 830 return MICROBIT_CANCELLED;
Jonathan Austin 1:8aa5cdb4ab67 831 }
Jonathan Austin 1:8aa5cdb4ab67 832
Jonathan Austin 1:8aa5cdb4ab67 833 return MICROBIT_OK;
Jonathan Austin 1:8aa5cdb4ab67 834 }
Jonathan Austin 1:8aa5cdb4ab67 835
Jonathan Austin 1:8aa5cdb4ab67 836 /**
Jonathan Austin 1:8aa5cdb4ab67 837 * Scrolls the given image across the display, from right to left.
Jonathan Austin 1:8aa5cdb4ab67 838 * Blocks the calling thread until all the text has been displayed.
Jonathan Austin 1:8aa5cdb4ab67 839 *
Jonathan Austin 1:8aa5cdb4ab67 840 * @param image The image to display.
Jonathan Austin 1:8aa5cdb4ab67 841 *
Jonathan Austin 1:8aa5cdb4ab67 842 * @param delay The time between updates, in milliseconds. Defaults
Jonathan Austin 1:8aa5cdb4ab67 843 * to: MICROBIT_DEFAULT_SCROLL_SPEED.
Jonathan Austin 1:8aa5cdb4ab67 844 *
Jonathan Austin 1:8aa5cdb4ab67 845 * @param stride The number of pixels to shift by in each update. Defaults to MICROBIT_DEFAULT_SCROLL_STRIDE.
Jonathan Austin 1:8aa5cdb4ab67 846 *
Jonathan Austin 1:8aa5cdb4ab67 847 * @return MICROBIT_OK, MICROBIT_CANCELLED or MICROBIT_INVALID_PARAMETER.
Jonathan Austin 1:8aa5cdb4ab67 848 *
Jonathan Austin 1:8aa5cdb4ab67 849 * @code
Jonathan Austin 1:8aa5cdb4ab67 850 * MicrobitImage i("1,1,1,1,1\n1,1,1,1,1\n");
Jonathan Austin 1:8aa5cdb4ab67 851 * display.scroll(i,100,1);
Jonathan Austin 1:8aa5cdb4ab67 852 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 853 */
Jonathan Austin 1:8aa5cdb4ab67 854 int MicroBitDisplay::scroll(MicroBitImage image, int delay, int stride)
Jonathan Austin 1:8aa5cdb4ab67 855 {
Jonathan Austin 1:8aa5cdb4ab67 856 //sanitise the delay value
Jonathan Austin 1:8aa5cdb4ab67 857 if(delay <= 0)
Jonathan Austin 1:8aa5cdb4ab67 858 return MICROBIT_INVALID_PARAMETER;
Jonathan Austin 1:8aa5cdb4ab67 859
Jonathan Austin 1:8aa5cdb4ab67 860 // If there's an ongoing animation, wait for our turn to display.
Jonathan Austin 1:8aa5cdb4ab67 861 this->waitForFreeDisplay();
Jonathan Austin 1:8aa5cdb4ab67 862
Jonathan Austin 1:8aa5cdb4ab67 863 // If the display is free, it's our turn to display.
Jonathan Austin 1:8aa5cdb4ab67 864 // If someone called stopAnimation(), then we simply skip...
Jonathan Austin 1:8aa5cdb4ab67 865 if (animationMode == ANIMATION_MODE_NONE)
Jonathan Austin 1:8aa5cdb4ab67 866 {
Jonathan Austin 1:8aa5cdb4ab67 867 // Start the effect.
Jonathan Austin 1:8aa5cdb4ab67 868 this->scrollAsync(image, delay, stride);
Jonathan Austin 1:8aa5cdb4ab67 869
Jonathan Austin 1:8aa5cdb4ab67 870 // Wait for completion.
Jonathan Austin 1:8aa5cdb4ab67 871 fiberWait();
Jonathan Austin 1:8aa5cdb4ab67 872 }
Jonathan Austin 1:8aa5cdb4ab67 873 else
Jonathan Austin 1:8aa5cdb4ab67 874 {
Jonathan Austin 1:8aa5cdb4ab67 875 return MICROBIT_CANCELLED;
Jonathan Austin 1:8aa5cdb4ab67 876 }
Jonathan Austin 1:8aa5cdb4ab67 877
Jonathan Austin 1:8aa5cdb4ab67 878 return MICROBIT_OK;
Jonathan Austin 1:8aa5cdb4ab67 879 }
Jonathan Austin 1:8aa5cdb4ab67 880
Jonathan Austin 1:8aa5cdb4ab67 881 /**
Jonathan Austin 1:8aa5cdb4ab67 882 * "Animates" the current image across the display with a given stride, finishing on the last frame of the animation.
Jonathan Austin 1:8aa5cdb4ab67 883 * Returns immediately.
Jonathan Austin 1:8aa5cdb4ab67 884 *
Jonathan Austin 1:8aa5cdb4ab67 885 * @param image The image to display.
Jonathan Austin 1:8aa5cdb4ab67 886 *
Jonathan Austin 1:8aa5cdb4ab67 887 * @param delay The time to delay between each update of the display, in milliseconds.
Jonathan Austin 1:8aa5cdb4ab67 888 *
Jonathan Austin 1:8aa5cdb4ab67 889 * @param stride The number of pixels to shift by in each update.
Jonathan Austin 1:8aa5cdb4ab67 890 *
Jonathan Austin 1:8aa5cdb4ab67 891 * @param startingPosition the starting position on the display for the animation
Jonathan Austin 1:8aa5cdb4ab67 892 * to begin at. Defaults to MICROBIT_DISPLAY_ANIMATE_DEFAULT_POS.
Jonathan Austin 1:8aa5cdb4ab67 893 *
Jonathan Austin 1:8aa5cdb4ab67 894 * @return MICROBIT_OK, MICROBIT_BUSY if the screen is in use, or MICROBIT_INVALID_PARAMETER.
Jonathan Austin 1:8aa5cdb4ab67 895 *
Jonathan Austin 1:8aa5cdb4ab67 896 * @code
Jonathan Austin 1:8aa5cdb4ab67 897 * const int heart_w = 10;
Jonathan Austin 1:8aa5cdb4ab67 898 * const int heart_h = 5;
Jonathan Austin 1:8aa5cdb4ab67 899 * 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, };
Jonathan Austin 1:8aa5cdb4ab67 900 *
Jonathan Austin 1:8aa5cdb4ab67 901 * MicroBitImage i(heart_w,heart_h,heart);
Jonathan Austin 1:8aa5cdb4ab67 902 * display.animateAsync(i,100,5);
Jonathan Austin 1:8aa5cdb4ab67 903 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 904 */
Jonathan Austin 1:8aa5cdb4ab67 905 int MicroBitDisplay::animateAsync(MicroBitImage image, int delay, int stride, int startingPosition)
Jonathan Austin 1:8aa5cdb4ab67 906 {
Jonathan Austin 1:8aa5cdb4ab67 907 //sanitise the delay value
Jonathan Austin 1:8aa5cdb4ab67 908 if(delay <= 0)
Jonathan Austin 1:8aa5cdb4ab67 909 return MICROBIT_INVALID_PARAMETER;
Jonathan Austin 1:8aa5cdb4ab67 910
Jonathan Austin 1:8aa5cdb4ab67 911 // If the display is free, we can display.
Jonathan Austin 1:8aa5cdb4ab67 912 if (animationMode == ANIMATION_MODE_NONE || animationMode == ANIMATION_MODE_STOPPED)
Jonathan Austin 1:8aa5cdb4ab67 913 {
Jonathan Austin 1:8aa5cdb4ab67 914 // Assume right to left functionality, to align with scrollString()
Jonathan Austin 1:8aa5cdb4ab67 915 stride = -stride;
Jonathan Austin 1:8aa5cdb4ab67 916
Jonathan Austin 1:8aa5cdb4ab67 917 //calculate starting position which is offset by the stride
Jonathan Austin 1:8aa5cdb4ab67 918 scrollingImagePosition = (startingPosition == MICROBIT_DISPLAY_ANIMATE_DEFAULT_POS) ? MICROBIT_DISPLAY_WIDTH + stride : startingPosition;
Jonathan Austin 1:8aa5cdb4ab67 919 scrollingImageStride = stride;
Jonathan Austin 1:8aa5cdb4ab67 920 scrollingImage = image;
Jonathan Austin 1:8aa5cdb4ab67 921 scrollingImageRendered = false;
Jonathan Austin 1:8aa5cdb4ab67 922
Jonathan Austin 1:8aa5cdb4ab67 923 animationDelay = stride == 0 ? 0 : delay;
Jonathan Austin 1:8aa5cdb4ab67 924 animationTick = delay-1;
Jonathan Austin 1:8aa5cdb4ab67 925 animationMode = ANIMATION_MODE_ANIMATE_IMAGE;
Jonathan Austin 1:8aa5cdb4ab67 926 }
Jonathan Austin 1:8aa5cdb4ab67 927 else
Jonathan Austin 1:8aa5cdb4ab67 928 {
Jonathan Austin 1:8aa5cdb4ab67 929 return MICROBIT_BUSY;
Jonathan Austin 1:8aa5cdb4ab67 930 }
Jonathan Austin 1:8aa5cdb4ab67 931
Jonathan Austin 1:8aa5cdb4ab67 932 return MICROBIT_OK;
Jonathan Austin 1:8aa5cdb4ab67 933 }
Jonathan Austin 1:8aa5cdb4ab67 934
Jonathan Austin 1:8aa5cdb4ab67 935 /**
Jonathan Austin 1:8aa5cdb4ab67 936 * "Animates" the current image across the display with a given stride, finishing on the last frame of the animation.
Jonathan Austin 1:8aa5cdb4ab67 937 * Blocks the calling thread until the animation is complete.
Jonathan Austin 1:8aa5cdb4ab67 938 *
Jonathan Austin 1:8aa5cdb4ab67 939 *
Jonathan Austin 1:8aa5cdb4ab67 940 * @param delay The time to delay between each update of the display, in milliseconds.
Jonathan Austin 1:8aa5cdb4ab67 941 *
Jonathan Austin 1:8aa5cdb4ab67 942 * @param stride The number of pixels to shift by in each update.
Jonathan Austin 1:8aa5cdb4ab67 943 *
Jonathan Austin 1:8aa5cdb4ab67 944 * @param startingPosition the starting position on the display for the animation
Jonathan Austin 1:8aa5cdb4ab67 945 * to begin at. Defaults to MICROBIT_DISPLAY_ANIMATE_DEFAULT_POS.
Jonathan Austin 1:8aa5cdb4ab67 946 *
Jonathan Austin 1:8aa5cdb4ab67 947 * @return MICROBIT_OK, MICROBIT_CANCELLED or MICROBIT_INVALID_PARAMETER.
Jonathan Austin 1:8aa5cdb4ab67 948 *
Jonathan Austin 1:8aa5cdb4ab67 949 * @code
Jonathan Austin 1:8aa5cdb4ab67 950 * const int heart_w = 10;
Jonathan Austin 1:8aa5cdb4ab67 951 * const int heart_h = 5;
Jonathan Austin 1:8aa5cdb4ab67 952 * 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, };
Jonathan Austin 1:8aa5cdb4ab67 953 *
Jonathan Austin 1:8aa5cdb4ab67 954 * MicroBitImage i(heart_w,heart_h,heart);
Jonathan Austin 1:8aa5cdb4ab67 955 * display.animate(i,100,5);
Jonathan Austin 1:8aa5cdb4ab67 956 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 957 */
Jonathan Austin 1:8aa5cdb4ab67 958 int MicroBitDisplay::animate(MicroBitImage image, int delay, int stride, int startingPosition)
Jonathan Austin 1:8aa5cdb4ab67 959 {
Jonathan Austin 1:8aa5cdb4ab67 960 //sanitise the delay value
Jonathan Austin 1:8aa5cdb4ab67 961 if(delay <= 0)
Jonathan Austin 1:8aa5cdb4ab67 962 return MICROBIT_INVALID_PARAMETER;
Jonathan Austin 1:8aa5cdb4ab67 963
Jonathan Austin 1:8aa5cdb4ab67 964 // If there's an ongoing animation, wait for our turn to display.
Jonathan Austin 1:8aa5cdb4ab67 965 this->waitForFreeDisplay();
Jonathan Austin 1:8aa5cdb4ab67 966
Jonathan Austin 1:8aa5cdb4ab67 967 // If the display is free, it's our turn to display.
Jonathan Austin 1:8aa5cdb4ab67 968 // If someone called stopAnimation(), then we simply skip...
Jonathan Austin 1:8aa5cdb4ab67 969 if (animationMode == ANIMATION_MODE_NONE)
Jonathan Austin 1:8aa5cdb4ab67 970 {
Jonathan Austin 1:8aa5cdb4ab67 971 // Start the effect.
Jonathan Austin 1:8aa5cdb4ab67 972 this->animateAsync(image, delay, stride, startingPosition);
Jonathan Austin 1:8aa5cdb4ab67 973
Jonathan Austin 1:8aa5cdb4ab67 974 // Wait for completion.
Jonathan Austin 1:8aa5cdb4ab67 975 //TODO: Put this in when we merge tight-validation
Jonathan Austin 1:8aa5cdb4ab67 976 //if (delay > 0)
Jonathan Austin 1:8aa5cdb4ab67 977 fiberWait();
Jonathan Austin 1:8aa5cdb4ab67 978 }
Jonathan Austin 1:8aa5cdb4ab67 979 else
Jonathan Austin 1:8aa5cdb4ab67 980 {
Jonathan Austin 1:8aa5cdb4ab67 981 return MICROBIT_CANCELLED;
Jonathan Austin 1:8aa5cdb4ab67 982 }
Jonathan Austin 1:8aa5cdb4ab67 983
Jonathan Austin 1:8aa5cdb4ab67 984 return MICROBIT_OK;
Jonathan Austin 1:8aa5cdb4ab67 985 }
Jonathan Austin 1:8aa5cdb4ab67 986
Jonathan Austin 1:8aa5cdb4ab67 987
Jonathan Austin 1:8aa5cdb4ab67 988 /**
Jonathan Austin 1:8aa5cdb4ab67 989 * Configures the brightness of the display.
Jonathan Austin 1:8aa5cdb4ab67 990 *
Jonathan Austin 1:8aa5cdb4ab67 991 * @param b The brightness to set the brightness to, in the range 0 - 255.
Jonathan Austin 1:8aa5cdb4ab67 992 *
Jonathan Austin 1:8aa5cdb4ab67 993 * @return MICROBIT_OK, or MICROBIT_INVALID_PARAMETER
Jonathan Austin 1:8aa5cdb4ab67 994 *
Jonathan Austin 1:8aa5cdb4ab67 995 * @code
Jonathan Austin 1:8aa5cdb4ab67 996 * display.setBrightness(255); //max brightness
Jonathan Austin 1:8aa5cdb4ab67 997 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 998 */
Jonathan Austin 1:8aa5cdb4ab67 999 int MicroBitDisplay::setBrightness(int b)
Jonathan Austin 1:8aa5cdb4ab67 1000 {
Jonathan Austin 1:8aa5cdb4ab67 1001 //sanitise the brightness level
Jonathan Austin 1:8aa5cdb4ab67 1002 if(b < 0 || b > 255)
Jonathan Austin 1:8aa5cdb4ab67 1003 return MICROBIT_INVALID_PARAMETER;
Jonathan Austin 1:8aa5cdb4ab67 1004
Jonathan Austin 1:8aa5cdb4ab67 1005 this->brightness = b;
Jonathan Austin 1:8aa5cdb4ab67 1006
Jonathan Austin 1:8aa5cdb4ab67 1007 return MICROBIT_OK;
Jonathan Austin 1:8aa5cdb4ab67 1008 }
Jonathan Austin 1:8aa5cdb4ab67 1009
Jonathan Austin 1:8aa5cdb4ab67 1010 /**
Jonathan Austin 1:8aa5cdb4ab67 1011 * Configures the mode of the display.
Jonathan Austin 1:8aa5cdb4ab67 1012 *
Jonathan Austin 1:8aa5cdb4ab67 1013 * @param mode The mode to swap the display into. One of: DISPLAY_MODE_GREYSCALE,
Jonathan Austin 1:8aa5cdb4ab67 1014 * DISPLAY_MODE_BLACK_AND_WHITE, DISPLAY_MODE_BLACK_AND_WHITE_LIGHT_SENSE
Jonathan Austin 1:8aa5cdb4ab67 1015 *
Jonathan Austin 1:8aa5cdb4ab67 1016 * @code
Jonathan Austin 1:8aa5cdb4ab67 1017 * display.setDisplayMode(DISPLAY_MODE_GREYSCALE); //per pixel brightness
Jonathan Austin 1:8aa5cdb4ab67 1018 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 1019 */
Jonathan Austin 1:8aa5cdb4ab67 1020 void MicroBitDisplay::setDisplayMode(DisplayMode mode)
Jonathan Austin 1:8aa5cdb4ab67 1021 {
Jonathan Austin 1:8aa5cdb4ab67 1022 if(mode == DISPLAY_MODE_BLACK_AND_WHITE_LIGHT_SENSE)
Jonathan Austin 1:8aa5cdb4ab67 1023 {
Jonathan Austin 1:8aa5cdb4ab67 1024 //to reduce the artifacts on the display - increase the tick
Jonathan Austin 1:8aa5cdb4ab67 1025 if(system_timer_get_period() != MICROBIT_LIGHT_SENSOR_TICK_PERIOD)
Jonathan Austin 1:8aa5cdb4ab67 1026 system_timer_set_period(MICROBIT_LIGHT_SENSOR_TICK_PERIOD);
Jonathan Austin 1:8aa5cdb4ab67 1027 }
Jonathan Austin 1:8aa5cdb4ab67 1028
Jonathan Austin 1:8aa5cdb4ab67 1029 if(this->mode == DISPLAY_MODE_BLACK_AND_WHITE_LIGHT_SENSE && mode != DISPLAY_MODE_BLACK_AND_WHITE_LIGHT_SENSE)
Jonathan Austin 1:8aa5cdb4ab67 1030 {
Jonathan Austin 1:8aa5cdb4ab67 1031 delete this->lightSensor;
Jonathan Austin 1:8aa5cdb4ab67 1032
Jonathan Austin 1:8aa5cdb4ab67 1033 this->lightSensor = NULL;
Jonathan Austin 1:8aa5cdb4ab67 1034 }
Jonathan Austin 1:8aa5cdb4ab67 1035
Jonathan Austin 1:8aa5cdb4ab67 1036 this->mode = mode;
Jonathan Austin 1:8aa5cdb4ab67 1037 }
Jonathan Austin 1:8aa5cdb4ab67 1038
Jonathan Austin 1:8aa5cdb4ab67 1039 /**
Jonathan Austin 1:8aa5cdb4ab67 1040 * Retrieves the mode of the display.
Jonathan Austin 1:8aa5cdb4ab67 1041 *
Jonathan Austin 1:8aa5cdb4ab67 1042 * @return the current mode of the display
Jonathan Austin 1:8aa5cdb4ab67 1043 */
Jonathan Austin 1:8aa5cdb4ab67 1044 int MicroBitDisplay::getDisplayMode()
Jonathan Austin 1:8aa5cdb4ab67 1045 {
Jonathan Austin 1:8aa5cdb4ab67 1046 return this->mode;
Jonathan Austin 1:8aa5cdb4ab67 1047 }
Jonathan Austin 1:8aa5cdb4ab67 1048
Jonathan Austin 1:8aa5cdb4ab67 1049 /**
Jonathan Austin 1:8aa5cdb4ab67 1050 * Fetches the current brightness of this display.
Jonathan Austin 1:8aa5cdb4ab67 1051 *
Jonathan Austin 1:8aa5cdb4ab67 1052 * @return the brightness of this display, in the range 0..255.
Jonathan Austin 1:8aa5cdb4ab67 1053 *
Jonathan Austin 1:8aa5cdb4ab67 1054 * @code
Jonathan Austin 1:8aa5cdb4ab67 1055 * display.getBrightness(); //the current brightness
Jonathan Austin 1:8aa5cdb4ab67 1056 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 1057 */
Jonathan Austin 1:8aa5cdb4ab67 1058 int MicroBitDisplay::getBrightness()
Jonathan Austin 1:8aa5cdb4ab67 1059 {
Jonathan Austin 1:8aa5cdb4ab67 1060 return this->brightness;
Jonathan Austin 1:8aa5cdb4ab67 1061 }
Jonathan Austin 1:8aa5cdb4ab67 1062
Jonathan Austin 1:8aa5cdb4ab67 1063 /**
Jonathan Austin 1:8aa5cdb4ab67 1064 * Rotates the display to the given position.
Jonathan Austin 1:8aa5cdb4ab67 1065 *
Jonathan Austin 1:8aa5cdb4ab67 1066 * Axis aligned values only.
Jonathan Austin 1:8aa5cdb4ab67 1067 *
Jonathan Austin 1:8aa5cdb4ab67 1068 * @code
Jonathan Austin 1:8aa5cdb4ab67 1069 * display.rotateTo(MICROBIT_DISPLAY_ROTATION_180); //rotates 180 degrees from original orientation
Jonathan Austin 1:8aa5cdb4ab67 1070 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 1071 */
Jonathan Austin 1:8aa5cdb4ab67 1072 void MicroBitDisplay::rotateTo(DisplayRotation rotation)
Jonathan Austin 1:8aa5cdb4ab67 1073 {
Jonathan Austin 1:8aa5cdb4ab67 1074 this->rotation = rotation;
Jonathan Austin 1:8aa5cdb4ab67 1075 }
Jonathan Austin 1:8aa5cdb4ab67 1076
Jonathan Austin 1:8aa5cdb4ab67 1077 /**
Jonathan Austin 1:8aa5cdb4ab67 1078 * Enables or disables the display entirely, and releases the pins for other uses.
Jonathan Austin 1:8aa5cdb4ab67 1079 *
Jonathan Austin 1:8aa5cdb4ab67 1080 * @param enableDisplay true to enabled the display, or false to disable it.
Jonathan Austin 1:8aa5cdb4ab67 1081 */
Jonathan Austin 1:8aa5cdb4ab67 1082 void MicroBitDisplay::setEnable(bool enableDisplay)
Jonathan Austin 1:8aa5cdb4ab67 1083 {
Jonathan Austin 1:8aa5cdb4ab67 1084 // If we're already in the correct state, then there's nothing to do.
Jonathan Austin 1:8aa5cdb4ab67 1085 if(((status & MICROBIT_COMPONENT_RUNNING) && enableDisplay) || (!(status & MICROBIT_COMPONENT_RUNNING) && !enableDisplay))
Jonathan Austin 1:8aa5cdb4ab67 1086 return;
Jonathan Austin 1:8aa5cdb4ab67 1087
Jonathan Austin 1:8aa5cdb4ab67 1088 uint32_t rmask = 0;
Jonathan Austin 1:8aa5cdb4ab67 1089 uint32_t cmask = 0;
Jonathan Austin 1:8aa5cdb4ab67 1090
Jonathan Austin 1:8aa5cdb4ab67 1091 for (int i = matrixMap.rowStart; i < matrixMap.rowStart + matrixMap.rows; i++)
Jonathan Austin 1:8aa5cdb4ab67 1092 rmask |= 0x01 << i;
Jonathan Austin 1:8aa5cdb4ab67 1093
Jonathan Austin 1:8aa5cdb4ab67 1094 for (int i = matrixMap.columnStart; i < matrixMap.columnStart + matrixMap.columns; i++)
Jonathan Austin 1:8aa5cdb4ab67 1095 cmask |= 0x01 << i;
Jonathan Austin 1:8aa5cdb4ab67 1096
Jonathan Austin 1:8aa5cdb4ab67 1097 if (enableDisplay)
Jonathan Austin 1:8aa5cdb4ab67 1098 {
Jonathan Austin 1:8aa5cdb4ab67 1099 PortOut p(Port0, rmask | cmask);
Jonathan Austin 1:8aa5cdb4ab67 1100 status |= MICROBIT_COMPONENT_RUNNING;
Jonathan Austin 1:8aa5cdb4ab67 1101 }
Jonathan Austin 1:8aa5cdb4ab67 1102 else
Jonathan Austin 1:8aa5cdb4ab67 1103 {
Jonathan Austin 1:8aa5cdb4ab67 1104 PortIn p(Port0, rmask | cmask);
Jonathan Austin 1:8aa5cdb4ab67 1105 p.mode(PullNone);
Jonathan Austin 1:8aa5cdb4ab67 1106 status &= ~MICROBIT_COMPONENT_RUNNING;
Jonathan Austin 1:8aa5cdb4ab67 1107 }
Jonathan Austin 1:8aa5cdb4ab67 1108 }
Jonathan Austin 1:8aa5cdb4ab67 1109
Jonathan Austin 1:8aa5cdb4ab67 1110 /**
Jonathan Austin 1:8aa5cdb4ab67 1111 * Enables the display, should only be called if the display is disabled.
Jonathan Austin 1:8aa5cdb4ab67 1112 *
Jonathan Austin 1:8aa5cdb4ab67 1113 * @code
Jonathan Austin 1:8aa5cdb4ab67 1114 * display.enable(); //Enables the display mechanics
Jonathan Austin 1:8aa5cdb4ab67 1115 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 1116 *
Jonathan Austin 1:8aa5cdb4ab67 1117 * @note Only enables the display if the display is currently disabled.
Jonathan Austin 1:8aa5cdb4ab67 1118 */
Jonathan Austin 1:8aa5cdb4ab67 1119 void MicroBitDisplay::enable()
Jonathan Austin 1:8aa5cdb4ab67 1120 {
Jonathan Austin 1:8aa5cdb4ab67 1121 setEnable(true);
Jonathan Austin 1:8aa5cdb4ab67 1122 }
Jonathan Austin 1:8aa5cdb4ab67 1123
Jonathan Austin 1:8aa5cdb4ab67 1124 /**
Jonathan Austin 1:8aa5cdb4ab67 1125 * Disables the display, which releases control of the GPIO pins used by the display,
Jonathan Austin 1:8aa5cdb4ab67 1126 * which are exposed on the edge connector.
Jonathan Austin 1:8aa5cdb4ab67 1127 *
Jonathan Austin 1:8aa5cdb4ab67 1128 * @code
Jonathan Austin 1:8aa5cdb4ab67 1129 * display.disable(); //disables the display
Jonathan Austin 1:8aa5cdb4ab67 1130 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 1131 *
Jonathan Austin 1:8aa5cdb4ab67 1132 * @note Only disables the display if the display is currently enabled.
Jonathan Austin 1:8aa5cdb4ab67 1133 */
Jonathan Austin 1:8aa5cdb4ab67 1134 void MicroBitDisplay::disable()
Jonathan Austin 1:8aa5cdb4ab67 1135 {
Jonathan Austin 1:8aa5cdb4ab67 1136 setEnable(false);
Jonathan Austin 1:8aa5cdb4ab67 1137 }
Jonathan Austin 1:8aa5cdb4ab67 1138
Jonathan Austin 1:8aa5cdb4ab67 1139 /**
Jonathan Austin 1:8aa5cdb4ab67 1140 * Clears the display of any remaining pixels.
Jonathan Austin 1:8aa5cdb4ab67 1141 *
Jonathan Austin 1:8aa5cdb4ab67 1142 * `display.image.clear()` can also be used!
Jonathan Austin 1:8aa5cdb4ab67 1143 *
Jonathan Austin 1:8aa5cdb4ab67 1144 * @code
Jonathan Austin 1:8aa5cdb4ab67 1145 * display.clear(); //clears the display
Jonathan Austin 1:8aa5cdb4ab67 1146 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 1147 */
Jonathan Austin 1:8aa5cdb4ab67 1148 void MicroBitDisplay::clear()
Jonathan Austin 1:8aa5cdb4ab67 1149 {
Jonathan Austin 1:8aa5cdb4ab67 1150 image.clear();
Jonathan Austin 1:8aa5cdb4ab67 1151 }
Jonathan Austin 1:8aa5cdb4ab67 1152
Jonathan Austin 1:8aa5cdb4ab67 1153 /**
Jonathan Austin 1:8aa5cdb4ab67 1154 * Updates the font that will be used for display operations.
Jonathan Austin 1:8aa5cdb4ab67 1155 *
Jonathan Austin 1:8aa5cdb4ab67 1156 * @param font the new font that will be used to render characters.
Jonathan Austin 1:8aa5cdb4ab67 1157 *
Jonathan Austin 1:8aa5cdb4ab67 1158 * @note DEPRECATED! Please use MicroBitFont::setSystemFont() instead.
Jonathan Austin 1:8aa5cdb4ab67 1159 */
Jonathan Austin 1:8aa5cdb4ab67 1160 void MicroBitDisplay::setFont(MicroBitFont font)
Jonathan Austin 1:8aa5cdb4ab67 1161 {
Jonathan Austin 1:8aa5cdb4ab67 1162 MicroBitFont::setSystemFont(font);
Jonathan Austin 1:8aa5cdb4ab67 1163 }
Jonathan Austin 1:8aa5cdb4ab67 1164
Jonathan Austin 1:8aa5cdb4ab67 1165 /**
Jonathan Austin 1:8aa5cdb4ab67 1166 * Retrieves the font object used for rendering characters on the display.
Jonathan Austin 1:8aa5cdb4ab67 1167 *
Jonathan Austin 1:8aa5cdb4ab67 1168 * @note DEPRECATED! Please use MicroBitFont::getSystemFont() instead.
Jonathan Austin 1:8aa5cdb4ab67 1169 */
Jonathan Austin 1:8aa5cdb4ab67 1170 MicroBitFont MicroBitDisplay::getFont()
Jonathan Austin 1:8aa5cdb4ab67 1171 {
Jonathan Austin 1:8aa5cdb4ab67 1172 return MicroBitFont::getSystemFont();
Jonathan Austin 1:8aa5cdb4ab67 1173 }
Jonathan Austin 1:8aa5cdb4ab67 1174
Jonathan Austin 1:8aa5cdb4ab67 1175 /**
Jonathan Austin 1:8aa5cdb4ab67 1176 * Captures the bitmap currently being rendered on the display.
Jonathan Austin 1:8aa5cdb4ab67 1177 *
Jonathan Austin 1:8aa5cdb4ab67 1178 * @return a MicroBitImage containing the captured data.
Jonathan Austin 1:8aa5cdb4ab67 1179 */
Jonathan Austin 1:8aa5cdb4ab67 1180 MicroBitImage MicroBitDisplay::screenShot()
Jonathan Austin 1:8aa5cdb4ab67 1181 {
Jonathan Austin 1:8aa5cdb4ab67 1182 return image.crop(0,0,MICROBIT_DISPLAY_WIDTH,MICROBIT_DISPLAY_HEIGHT);
Jonathan Austin 1:8aa5cdb4ab67 1183 }
Jonathan Austin 1:8aa5cdb4ab67 1184
Jonathan Austin 1:8aa5cdb4ab67 1185 /**
Jonathan Austin 1:8aa5cdb4ab67 1186 * Gives a representative figure of the light level in the current environment
Jonathan Austin 1:8aa5cdb4ab67 1187 * where are micro:bit is situated.
Jonathan Austin 1:8aa5cdb4ab67 1188 *
Jonathan Austin 1:8aa5cdb4ab67 1189 * Internally, it constructs an instance of a MicroBitLightSensor if not already configured
Jonathan Austin 1:8aa5cdb4ab67 1190 * and sets the display mode to DISPLAY_MODE_BLACK_AND_WHITE_LIGHT_SENSE.
Jonathan Austin 1:8aa5cdb4ab67 1191 *
Jonathan Austin 1:8aa5cdb4ab67 1192 * This also changes the tickPeriod to MICROBIT_LIGHT_SENSOR_TICK_SPEED so
Jonathan Austin 1:8aa5cdb4ab67 1193 * that the display does not suffer from artifacts.
Jonathan Austin 1:8aa5cdb4ab67 1194 *
Jonathan Austin 1:8aa5cdb4ab67 1195 * @return an indicative light level in the range 0 - 255.
Jonathan Austin 1:8aa5cdb4ab67 1196 *
Jonathan Austin 1:8aa5cdb4ab67 1197 * @note this will return 0 on the first call to this method, a light reading
Jonathan Austin 1:8aa5cdb4ab67 1198 * will be available after the display has activated the light sensor for the
Jonathan Austin 1:8aa5cdb4ab67 1199 * first time.
Jonathan Austin 1:8aa5cdb4ab67 1200 */
Jonathan Austin 1:8aa5cdb4ab67 1201 int MicroBitDisplay::readLightLevel()
Jonathan Austin 1:8aa5cdb4ab67 1202 {
Jonathan Austin 1:8aa5cdb4ab67 1203 if(mode != DISPLAY_MODE_BLACK_AND_WHITE_LIGHT_SENSE)
Jonathan Austin 1:8aa5cdb4ab67 1204 {
Jonathan Austin 1:8aa5cdb4ab67 1205 setDisplayMode(DISPLAY_MODE_BLACK_AND_WHITE_LIGHT_SENSE);
Jonathan Austin 1:8aa5cdb4ab67 1206 this->lightSensor = new MicroBitLightSensor(matrixMap);
Jonathan Austin 1:8aa5cdb4ab67 1207 }
Jonathan Austin 1:8aa5cdb4ab67 1208
Jonathan Austin 1:8aa5cdb4ab67 1209 return this->lightSensor->read();
Jonathan Austin 1:8aa5cdb4ab67 1210 }
Jonathan Austin 1:8aa5cdb4ab67 1211
Jonathan Austin 1:8aa5cdb4ab67 1212 /**
Jonathan Austin 1:8aa5cdb4ab67 1213 * Destructor for MicroBitDisplay, where we deregister this instance from the array of system components.
Jonathan Austin 1:8aa5cdb4ab67 1214 */
Jonathan Austin 1:8aa5cdb4ab67 1215 MicroBitDisplay::~MicroBitDisplay()
Jonathan Austin 1:8aa5cdb4ab67 1216 {
Jonathan Austin 1:8aa5cdb4ab67 1217 system_timer_remove_component(this);
Jonathan Austin 1:8aa5cdb4ab67 1218 }