Solution for Bluetooth SIG hands-on training course

Dependencies:   BLE_API mbed-dev-bin nRF51822-bluetooth-mdw

Dependents:   microbit

Fork of microbit-dal-bluetooth-mdw_starter by Martin Woolley

Committer:
LancasterUniversity
Date:
Wed Jul 13 12:17:54 2016 +0100
Revision:
22:23d7b9a4b082
Parent:
21:cab56b701601
Child:
23:6055f6c19fa6
Synchronized with git rev 7cf98c22
Author: James Devine
microbit-dal: patch for fiber_wake_on_event

fiber_wake_on_event used to crash after forking a FOB fiber.

It would attempt to obtain a new fiber context, and would place it on the wait queue.
Then when that fiber was paged in, the context of that fiber would not have been
initialised, as the function presumed schedule would be called immediately after
fiber initialisation.

This patch catches that edge case.

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
LancasterUniversity 22:23d7b9a4b082 290 if (animationMode == ANIMATION_MODE_ANIMATE_IMAGE || animationMode == ANIMATION_MODE_ANIMATE_IMAGE_WITH_CLEAR)
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 {
LancasterUniversity 22:23d7b9a4b082 387 if (animationMode == ANIMATION_MODE_ANIMATE_IMAGE_WITH_CLEAR)
LancasterUniversity 22:23d7b9a4b082 388 this->clear();
LancasterUniversity 22:23d7b9a4b082 389
Jonathan Austin 1:8aa5cdb4ab67 390 animationMode = ANIMATION_MODE_NONE;
LancasterUniversity 22:23d7b9a4b082 391
Jonathan Austin 1:8aa5cdb4ab67 392 this->sendAnimationCompleteEvent();
Jonathan Austin 1:8aa5cdb4ab67 393 return;
Jonathan Austin 1:8aa5cdb4ab67 394 }
Jonathan Austin 1:8aa5cdb4ab67 395
Jonathan Austin 1:8aa5cdb4ab67 396 if(scrollingImagePosition > 0)
Jonathan Austin 1:8aa5cdb4ab67 397 image.shiftLeft(-scrollingImageStride);
Jonathan Austin 1:8aa5cdb4ab67 398
Jonathan Austin 1:8aa5cdb4ab67 399 image.paste(scrollingImage, scrollingImagePosition, 0, 0);
Jonathan Austin 1:8aa5cdb4ab67 400
Jonathan Austin 1:8aa5cdb4ab67 401 if(scrollingImageStride == 0)
Jonathan Austin 1:8aa5cdb4ab67 402 {
Jonathan Austin 1:8aa5cdb4ab67 403 animationMode = ANIMATION_MODE_NONE;
Jonathan Austin 1:8aa5cdb4ab67 404 this->sendAnimationCompleteEvent();
Jonathan Austin 1:8aa5cdb4ab67 405 }
Jonathan Austin 1:8aa5cdb4ab67 406
Jonathan Austin 1:8aa5cdb4ab67 407 scrollingImageRendered = true;
Jonathan Austin 1:8aa5cdb4ab67 408
Jonathan Austin 1:8aa5cdb4ab67 409 scrollingImagePosition += scrollingImageStride;
Jonathan Austin 1:8aa5cdb4ab67 410 }
Jonathan Austin 1:8aa5cdb4ab67 411
Jonathan Austin 1:8aa5cdb4ab67 412 /**
Jonathan Austin 1:8aa5cdb4ab67 413 * Resets the current given animation.
Jonathan Austin 1:8aa5cdb4ab67 414 */
Jonathan Austin 1:8aa5cdb4ab67 415 void MicroBitDisplay::stopAnimation()
Jonathan Austin 1:8aa5cdb4ab67 416 {
Jonathan Austin 1:8aa5cdb4ab67 417 // Reset any ongoing animation.
Jonathan Austin 1:8aa5cdb4ab67 418 if (animationMode != ANIMATION_MODE_NONE)
Jonathan Austin 1:8aa5cdb4ab67 419 {
Jonathan Austin 1:8aa5cdb4ab67 420 animationMode = ANIMATION_MODE_NONE;
Jonathan Austin 1:8aa5cdb4ab67 421
Jonathan Austin 1:8aa5cdb4ab67 422 // Indicate that we've completed an animation.
Jonathan Austin 1:8aa5cdb4ab67 423 MicroBitEvent(id,MICROBIT_DISPLAY_EVT_ANIMATION_COMPLETE);
Jonathan Austin 1:8aa5cdb4ab67 424
Jonathan Austin 1:8aa5cdb4ab67 425 // Wake up aall fibers that may blocked on the animation (if any).
Jonathan Austin 1:8aa5cdb4ab67 426 MicroBitEvent(MICROBIT_ID_NOTIFY, MICROBIT_DISPLAY_EVT_FREE);
Jonathan Austin 1:8aa5cdb4ab67 427 }
Jonathan Austin 1:8aa5cdb4ab67 428
Jonathan Austin 1:8aa5cdb4ab67 429 // Clear the display and setup the animation timers.
Jonathan Austin 1:8aa5cdb4ab67 430 this->image.clear();
Jonathan Austin 1:8aa5cdb4ab67 431 }
Jonathan Austin 1:8aa5cdb4ab67 432
Jonathan Austin 1:8aa5cdb4ab67 433 /**
Jonathan Austin 1:8aa5cdb4ab67 434 * Blocks the current fiber until the display is available (i.e. does not effect is being displayed).
Jonathan Austin 1:8aa5cdb4ab67 435 * Animations are queued until their time to display.
Jonathan Austin 1:8aa5cdb4ab67 436 */
Jonathan Austin 1:8aa5cdb4ab67 437 void MicroBitDisplay::waitForFreeDisplay()
Jonathan Austin 1:8aa5cdb4ab67 438 {
Jonathan Austin 1:8aa5cdb4ab67 439 // If there's an ongoing animation, wait for our turn to display.
Jonathan Austin 1:8aa5cdb4ab67 440 if (animationMode != ANIMATION_MODE_NONE && animationMode != ANIMATION_MODE_STOPPED)
Jonathan Austin 1:8aa5cdb4ab67 441 fiber_wait_for_event(MICROBIT_ID_NOTIFY, MICROBIT_DISPLAY_EVT_FREE);
Jonathan Austin 1:8aa5cdb4ab67 442 }
Jonathan Austin 1:8aa5cdb4ab67 443
Jonathan Austin 1:8aa5cdb4ab67 444 /**
Jonathan Austin 1:8aa5cdb4ab67 445 * Blocks the current fiber until the current animation has finished.
Jonathan Austin 1:8aa5cdb4ab67 446 * If the scheduler is not running, this call will essentially perform a spinning wait.
Jonathan Austin 1:8aa5cdb4ab67 447 */
Jonathan Austin 1:8aa5cdb4ab67 448 void MicroBitDisplay::fiberWait()
Jonathan Austin 1:8aa5cdb4ab67 449 {
Jonathan Austin 1:8aa5cdb4ab67 450 if (fiber_wait_for_event(MICROBIT_ID_DISPLAY, MICROBIT_DISPLAY_EVT_ANIMATION_COMPLETE) == MICROBIT_NOT_SUPPORTED)
Jonathan Austin 1:8aa5cdb4ab67 451 while(animationMode != ANIMATION_MODE_NONE && animationMode != ANIMATION_MODE_STOPPED)
Jonathan Austin 1:8aa5cdb4ab67 452 __WFE();
Jonathan Austin 1:8aa5cdb4ab67 453 }
Jonathan Austin 1:8aa5cdb4ab67 454
Jonathan Austin 1:8aa5cdb4ab67 455 /**
Jonathan Austin 1:8aa5cdb4ab67 456 * Prints the given character to the display, if it is not in use.
Jonathan Austin 1:8aa5cdb4ab67 457 *
Jonathan Austin 1:8aa5cdb4ab67 458 * @param c The character to display.
Jonathan Austin 1:8aa5cdb4ab67 459 *
Jonathan Austin 1:8aa5cdb4ab67 460 * @param delay Optional parameter - the time for which to show the character. Zero displays the character forever,
Jonathan Austin 1:8aa5cdb4ab67 461 * or until the Displays next use.
Jonathan Austin 1:8aa5cdb4ab67 462 *
Jonathan Austin 1:8aa5cdb4ab67 463 * @return MICROBIT_OK, MICROBIT_BUSY is the screen is in use, or MICROBIT_INVALID_PARAMETER.
Jonathan Austin 1:8aa5cdb4ab67 464 *
Jonathan Austin 1:8aa5cdb4ab67 465 * @code
Jonathan Austin 1:8aa5cdb4ab67 466 * display.printAsync('p');
Jonathan Austin 1:8aa5cdb4ab67 467 * display.printAsync('p',100);
Jonathan Austin 1:8aa5cdb4ab67 468 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 469 */
Jonathan Austin 1:8aa5cdb4ab67 470 int MicroBitDisplay::printCharAsync(char c, int delay)
Jonathan Austin 1:8aa5cdb4ab67 471 {
Jonathan Austin 1:8aa5cdb4ab67 472 //sanitise this value
Jonathan Austin 1:8aa5cdb4ab67 473 if(delay < 0)
Jonathan Austin 1:8aa5cdb4ab67 474 return MICROBIT_INVALID_PARAMETER;
Jonathan Austin 1:8aa5cdb4ab67 475
Jonathan Austin 1:8aa5cdb4ab67 476 // If the display is free, it's our turn to display.
Jonathan Austin 1:8aa5cdb4ab67 477 if (animationMode == ANIMATION_MODE_NONE || animationMode == ANIMATION_MODE_STOPPED)
Jonathan Austin 1:8aa5cdb4ab67 478 {
Jonathan Austin 1:8aa5cdb4ab67 479 image.print(c, 0, 0);
Jonathan Austin 1:8aa5cdb4ab67 480
Jonathan Austin 1:8aa5cdb4ab67 481 if (delay > 0)
Jonathan Austin 1:8aa5cdb4ab67 482 {
Jonathan Austin 1:8aa5cdb4ab67 483 animationDelay = delay;
Jonathan Austin 1:8aa5cdb4ab67 484 animationTick = 0;
Jonathan Austin 1:8aa5cdb4ab67 485 animationMode = ANIMATION_MODE_PRINT_CHARACTER;
Jonathan Austin 1:8aa5cdb4ab67 486 }
Jonathan Austin 1:8aa5cdb4ab67 487 }
Jonathan Austin 1:8aa5cdb4ab67 488 else
Jonathan Austin 1:8aa5cdb4ab67 489 {
Jonathan Austin 1:8aa5cdb4ab67 490 return MICROBIT_BUSY;
Jonathan Austin 1:8aa5cdb4ab67 491 }
Jonathan Austin 1:8aa5cdb4ab67 492
Jonathan Austin 1:8aa5cdb4ab67 493 return MICROBIT_OK;
Jonathan Austin 1:8aa5cdb4ab67 494 }
Jonathan Austin 1:8aa5cdb4ab67 495
Jonathan Austin 1:8aa5cdb4ab67 496 /**
Jonathan Austin 1:8aa5cdb4ab67 497 * Prints the given ManagedString to the display, one character at a time.
Jonathan Austin 1:8aa5cdb4ab67 498 * Returns immediately, and executes the animation asynchronously.
Jonathan Austin 1:8aa5cdb4ab67 499 *
Jonathan Austin 1:8aa5cdb4ab67 500 * @param s The string to display.
Jonathan Austin 1:8aa5cdb4ab67 501 *
Jonathan Austin 1:8aa5cdb4ab67 502 * @param delay The time to delay between characters, in milliseconds. Must be > 0.
Jonathan Austin 1:8aa5cdb4ab67 503 * Defaults to: MICROBIT_DEFAULT_PRINT_SPEED.
Jonathan Austin 1:8aa5cdb4ab67 504 *
Jonathan Austin 1:8aa5cdb4ab67 505 * @return MICROBIT_OK, or MICROBIT_INVALID_PARAMETER.
Jonathan Austin 1:8aa5cdb4ab67 506 *
Jonathan Austin 1:8aa5cdb4ab67 507 * @code
Jonathan Austin 1:8aa5cdb4ab67 508 * display.printAsync("abc123",400);
Jonathan Austin 1:8aa5cdb4ab67 509 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 510 */
Jonathan Austin 1:8aa5cdb4ab67 511 int MicroBitDisplay::printAsync(ManagedString s, int delay)
Jonathan Austin 1:8aa5cdb4ab67 512 {
Jonathan Austin 1:8aa5cdb4ab67 513 if (s.length() == 1)
Jonathan Austin 1:8aa5cdb4ab67 514 return printCharAsync(s.charAt(0));
Jonathan Austin 1:8aa5cdb4ab67 515
Jonathan Austin 1:8aa5cdb4ab67 516 //sanitise this value
Jonathan Austin 1:8aa5cdb4ab67 517 if (delay <= 0 )
Jonathan Austin 1:8aa5cdb4ab67 518 return MICROBIT_INVALID_PARAMETER;
Jonathan Austin 1:8aa5cdb4ab67 519
Jonathan Austin 1:8aa5cdb4ab67 520 if (animationMode == ANIMATION_MODE_NONE || animationMode == ANIMATION_MODE_STOPPED)
Jonathan Austin 1:8aa5cdb4ab67 521 {
Jonathan Austin 1:8aa5cdb4ab67 522 printingChar = 0;
Jonathan Austin 1:8aa5cdb4ab67 523 printingText = s;
Jonathan Austin 1:8aa5cdb4ab67 524 animationDelay = delay;
Jonathan Austin 1:8aa5cdb4ab67 525 animationTick = 0;
Jonathan Austin 1:8aa5cdb4ab67 526
Jonathan Austin 1:8aa5cdb4ab67 527 animationMode = ANIMATION_MODE_PRINT_TEXT;
Jonathan Austin 1:8aa5cdb4ab67 528 }
Jonathan Austin 1:8aa5cdb4ab67 529 else
Jonathan Austin 1:8aa5cdb4ab67 530 {
Jonathan Austin 1:8aa5cdb4ab67 531 return MICROBIT_BUSY;
Jonathan Austin 1:8aa5cdb4ab67 532 }
Jonathan Austin 1:8aa5cdb4ab67 533
Jonathan Austin 1:8aa5cdb4ab67 534 return MICROBIT_OK;
Jonathan Austin 1:8aa5cdb4ab67 535 }
Jonathan Austin 1:8aa5cdb4ab67 536
Jonathan Austin 1:8aa5cdb4ab67 537 /**
Jonathan Austin 1:8aa5cdb4ab67 538 * Prints the given image to the display, if the display is not in use.
Jonathan Austin 1:8aa5cdb4ab67 539 * Returns immediately, and executes the animation asynchronously.
Jonathan Austin 1:8aa5cdb4ab67 540 *
Jonathan Austin 1:8aa5cdb4ab67 541 * @param i The image to display.
Jonathan Austin 1:8aa5cdb4ab67 542 *
Jonathan Austin 1:8aa5cdb4ab67 543 * @param x The horizontal position on the screen to display the image. Defaults to 0.
Jonathan Austin 1:8aa5cdb4ab67 544 *
Jonathan Austin 1:8aa5cdb4ab67 545 * @param y The vertical position on the screen to display the image. Defaults to 0.
Jonathan Austin 1:8aa5cdb4ab67 546 *
Jonathan Austin 1:8aa5cdb4ab67 547 * @param alpha Treats the brightness level '0' as transparent. Defaults to 0.
Jonathan Austin 1:8aa5cdb4ab67 548 *
Jonathan Austin 1:8aa5cdb4ab67 549 * @param delay The time to delay between characters, in milliseconds. Defaults to 0.
Jonathan Austin 1:8aa5cdb4ab67 550 *
Jonathan Austin 1:8aa5cdb4ab67 551 * @code
Jonathan Austin 1:8aa5cdb4ab67 552 * MicrobitImage i("1,1,1,1,1\n1,1,1,1,1\n");
Jonathan Austin 1:8aa5cdb4ab67 553 * display.print(i,400);
Jonathan Austin 1:8aa5cdb4ab67 554 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 555 */
Jonathan Austin 1:8aa5cdb4ab67 556 int MicroBitDisplay::printAsync(MicroBitImage i, int x, int y, int alpha, int delay)
Jonathan Austin 1:8aa5cdb4ab67 557 {
Jonathan Austin 1:8aa5cdb4ab67 558 if(delay < 0)
Jonathan Austin 1:8aa5cdb4ab67 559 return MICROBIT_INVALID_PARAMETER;
Jonathan Austin 1:8aa5cdb4ab67 560
Jonathan Austin 1:8aa5cdb4ab67 561 if (animationMode == ANIMATION_MODE_NONE || animationMode == ANIMATION_MODE_STOPPED)
Jonathan Austin 1:8aa5cdb4ab67 562 {
Jonathan Austin 1:8aa5cdb4ab67 563 image.paste(i, x, y, alpha);
Jonathan Austin 1:8aa5cdb4ab67 564
Jonathan Austin 1:8aa5cdb4ab67 565 if(delay > 0)
Jonathan Austin 1:8aa5cdb4ab67 566 {
Jonathan Austin 1:8aa5cdb4ab67 567 animationDelay = delay;
Jonathan Austin 1:8aa5cdb4ab67 568 animationTick = 0;
Jonathan Austin 1:8aa5cdb4ab67 569 animationMode = ANIMATION_MODE_PRINT_CHARACTER;
Jonathan Austin 1:8aa5cdb4ab67 570 }
Jonathan Austin 1:8aa5cdb4ab67 571 }
Jonathan Austin 1:8aa5cdb4ab67 572 else
Jonathan Austin 1:8aa5cdb4ab67 573 {
Jonathan Austin 1:8aa5cdb4ab67 574 return MICROBIT_BUSY;
Jonathan Austin 1:8aa5cdb4ab67 575 }
Jonathan Austin 1:8aa5cdb4ab67 576
Jonathan Austin 1:8aa5cdb4ab67 577 return MICROBIT_OK;
Jonathan Austin 1:8aa5cdb4ab67 578 }
Jonathan Austin 1:8aa5cdb4ab67 579
Jonathan Austin 1:8aa5cdb4ab67 580 /**
Jonathan Austin 1:8aa5cdb4ab67 581 * Prints the given character to the display.
Jonathan Austin 1:8aa5cdb4ab67 582 *
Jonathan Austin 1:8aa5cdb4ab67 583 * @param c The character to display.
Jonathan Austin 1:8aa5cdb4ab67 584 *
Jonathan Austin 1:8aa5cdb4ab67 585 * @param delay Optional parameter - the time for which to show the character. Zero displays the character forever,
Jonathan Austin 1:8aa5cdb4ab67 586 * or until the Displays next use.
Jonathan Austin 1:8aa5cdb4ab67 587 *
Jonathan Austin 1:8aa5cdb4ab67 588 * @return MICROBIT_OK, MICROBIT_CANCELLED or MICROBIT_INVALID_PARAMETER.
Jonathan Austin 1:8aa5cdb4ab67 589 *
Jonathan Austin 1:8aa5cdb4ab67 590 * @code
Jonathan Austin 1:8aa5cdb4ab67 591 * display.printAsync('p');
Jonathan Austin 1:8aa5cdb4ab67 592 * display.printAsync('p',100);
Jonathan Austin 1:8aa5cdb4ab67 593 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 594 */
Jonathan Austin 1:8aa5cdb4ab67 595 int MicroBitDisplay::printChar(char c, int delay)
Jonathan Austin 1:8aa5cdb4ab67 596 {
Jonathan Austin 1:8aa5cdb4ab67 597 if (delay < 0)
Jonathan Austin 1:8aa5cdb4ab67 598 return MICROBIT_INVALID_PARAMETER;
Jonathan Austin 1:8aa5cdb4ab67 599
Jonathan Austin 1:8aa5cdb4ab67 600 // If there's an ongoing animation, wait for our turn to display.
Jonathan Austin 1:8aa5cdb4ab67 601 this->waitForFreeDisplay();
Jonathan Austin 1:8aa5cdb4ab67 602
Jonathan Austin 1:8aa5cdb4ab67 603 // If the display is free, it's our turn to display.
Jonathan Austin 1:8aa5cdb4ab67 604 // If someone called stopAnimation(), then we simply skip...
Jonathan Austin 1:8aa5cdb4ab67 605 if (animationMode == ANIMATION_MODE_NONE)
Jonathan Austin 1:8aa5cdb4ab67 606 {
Jonathan Austin 1:8aa5cdb4ab67 607 this->printCharAsync(c, delay);
Jonathan Austin 1:8aa5cdb4ab67 608
Jonathan Austin 1:8aa5cdb4ab67 609 if (delay > 0)
Jonathan Austin 1:8aa5cdb4ab67 610 fiberWait();
Jonathan Austin 1:8aa5cdb4ab67 611 }
Jonathan Austin 1:8aa5cdb4ab67 612 else
Jonathan Austin 1:8aa5cdb4ab67 613 {
Jonathan Austin 1:8aa5cdb4ab67 614 return MICROBIT_CANCELLED;
Jonathan Austin 1:8aa5cdb4ab67 615 }
Jonathan Austin 1:8aa5cdb4ab67 616
Jonathan Austin 1:8aa5cdb4ab67 617 return MICROBIT_OK;
Jonathan Austin 1:8aa5cdb4ab67 618 }
Jonathan Austin 1:8aa5cdb4ab67 619
Jonathan Austin 1:8aa5cdb4ab67 620 /**
Jonathan Austin 1:8aa5cdb4ab67 621 * Prints the given string to the display, one character at a time.
Jonathan Austin 1:8aa5cdb4ab67 622 *
Jonathan Austin 1:8aa5cdb4ab67 623 * Blocks the calling thread until all the text has been displayed.
Jonathan Austin 1:8aa5cdb4ab67 624 *
Jonathan Austin 1:8aa5cdb4ab67 625 * @param s The string to display.
Jonathan Austin 1:8aa5cdb4ab67 626 *
Jonathan Austin 1:8aa5cdb4ab67 627 * @param delay The time to delay between characters, in milliseconds. Defaults
Jonathan Austin 1:8aa5cdb4ab67 628 * to: MICROBIT_DEFAULT_PRINT_SPEED.
Jonathan Austin 1:8aa5cdb4ab67 629 *
Jonathan Austin 1:8aa5cdb4ab67 630 * @return MICROBIT_OK, MICROBIT_CANCELLED or MICROBIT_INVALID_PARAMETER.
Jonathan Austin 1:8aa5cdb4ab67 631 *
Jonathan Austin 1:8aa5cdb4ab67 632 * @code
Jonathan Austin 1:8aa5cdb4ab67 633 * display.print("abc123",400);
Jonathan Austin 1:8aa5cdb4ab67 634 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 635 */
Jonathan Austin 1:8aa5cdb4ab67 636 int MicroBitDisplay::print(ManagedString s, int delay)
Jonathan Austin 1:8aa5cdb4ab67 637 {
Jonathan Austin 1:8aa5cdb4ab67 638 //sanitise this value
Jonathan Austin 1:8aa5cdb4ab67 639 if(delay <= 0 )
Jonathan Austin 1:8aa5cdb4ab67 640 return MICROBIT_INVALID_PARAMETER;
Jonathan Austin 1:8aa5cdb4ab67 641
Jonathan Austin 1:8aa5cdb4ab67 642 // If there's an ongoing animation, wait for our turn to display.
Jonathan Austin 1:8aa5cdb4ab67 643 this->waitForFreeDisplay();
Jonathan Austin 1:8aa5cdb4ab67 644
Jonathan Austin 1:8aa5cdb4ab67 645 // If the display is free, it's our turn to display.
Jonathan Austin 1:8aa5cdb4ab67 646 // If someone called stopAnimation(), then we simply skip...
Jonathan Austin 1:8aa5cdb4ab67 647 if (animationMode == ANIMATION_MODE_NONE)
Jonathan Austin 1:8aa5cdb4ab67 648 {
Jonathan Austin 1:8aa5cdb4ab67 649 if (s.length() == 1)
Jonathan Austin 1:8aa5cdb4ab67 650 {
Jonathan Austin 1:8aa5cdb4ab67 651 return printCharAsync(s.charAt(0));
Jonathan Austin 1:8aa5cdb4ab67 652 }
Jonathan Austin 1:8aa5cdb4ab67 653 else
Jonathan Austin 1:8aa5cdb4ab67 654 {
Jonathan Austin 1:8aa5cdb4ab67 655 this->printAsync(s, delay);
Jonathan Austin 1:8aa5cdb4ab67 656 fiberWait();
Jonathan Austin 1:8aa5cdb4ab67 657 }
Jonathan Austin 1:8aa5cdb4ab67 658 }
Jonathan Austin 1:8aa5cdb4ab67 659 else
Jonathan Austin 1:8aa5cdb4ab67 660 {
Jonathan Austin 1:8aa5cdb4ab67 661 return MICROBIT_CANCELLED;
Jonathan Austin 1:8aa5cdb4ab67 662 }
Jonathan Austin 1:8aa5cdb4ab67 663
Jonathan Austin 1:8aa5cdb4ab67 664 return MICROBIT_OK;
Jonathan Austin 1:8aa5cdb4ab67 665 }
Jonathan Austin 1:8aa5cdb4ab67 666
Jonathan Austin 1:8aa5cdb4ab67 667 /**
Jonathan Austin 1:8aa5cdb4ab67 668 * Prints the given image to the display.
Jonathan Austin 1:8aa5cdb4ab67 669 * Blocks the calling thread until all the image has been displayed.
Jonathan Austin 1:8aa5cdb4ab67 670 *
Jonathan Austin 1:8aa5cdb4ab67 671 * @param i The image to display.
Jonathan Austin 1:8aa5cdb4ab67 672 *
Jonathan Austin 1:8aa5cdb4ab67 673 * @param x The horizontal position on the screen to display the image. Defaults to 0.
Jonathan Austin 1:8aa5cdb4ab67 674 *
Jonathan Austin 1:8aa5cdb4ab67 675 * @param y The vertical position on the screen to display the image. Defaults to 0.
Jonathan Austin 1:8aa5cdb4ab67 676 *
Jonathan Austin 1:8aa5cdb4ab67 677 * @param alpha Treats the brightness level '0' as transparent. Defaults to 0.
Jonathan Austin 1:8aa5cdb4ab67 678 *
Jonathan Austin 1:8aa5cdb4ab67 679 * @param delay The time to display the image for, or zero to show the image forever. Defaults to 0.
Jonathan Austin 1:8aa5cdb4ab67 680 *
Jonathan Austin 1:8aa5cdb4ab67 681 * @return MICROBIT_OK, MICROBIT_BUSY if the display is already in use, or MICROBIT_INVALID_PARAMETER.
Jonathan Austin 1:8aa5cdb4ab67 682 *
Jonathan Austin 1:8aa5cdb4ab67 683 * @code
Jonathan Austin 1:8aa5cdb4ab67 684 * MicrobitImage i("1,1,1,1,1\n1,1,1,1,1\n");
Jonathan Austin 1:8aa5cdb4ab67 685 * display.print(i,400);
Jonathan Austin 1:8aa5cdb4ab67 686 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 687 */
Jonathan Austin 1:8aa5cdb4ab67 688 int MicroBitDisplay::print(MicroBitImage i, int x, int y, int alpha, int delay)
Jonathan Austin 1:8aa5cdb4ab67 689 {
Jonathan Austin 1:8aa5cdb4ab67 690 if(delay < 0)
Jonathan Austin 1:8aa5cdb4ab67 691 return MICROBIT_INVALID_PARAMETER;
Jonathan Austin 1:8aa5cdb4ab67 692
Jonathan Austin 1:8aa5cdb4ab67 693 // If there's an ongoing animation, wait for our turn to display.
Jonathan Austin 1:8aa5cdb4ab67 694 this->waitForFreeDisplay();
Jonathan Austin 1:8aa5cdb4ab67 695
Jonathan Austin 1:8aa5cdb4ab67 696 // If the display is free, it's our turn to display.
Jonathan Austin 1:8aa5cdb4ab67 697 // If someone called stopAnimation(), then we simply skip...
Jonathan Austin 1:8aa5cdb4ab67 698 if (animationMode == ANIMATION_MODE_NONE)
Jonathan Austin 1:8aa5cdb4ab67 699 {
Jonathan Austin 1:8aa5cdb4ab67 700 this->printAsync(i, x, y, alpha, delay);
Jonathan Austin 1:8aa5cdb4ab67 701
Jonathan Austin 1:8aa5cdb4ab67 702 if (delay > 0)
Jonathan Austin 1:8aa5cdb4ab67 703 fiberWait();
Jonathan Austin 1:8aa5cdb4ab67 704 }
Jonathan Austin 1:8aa5cdb4ab67 705 else
Jonathan Austin 1:8aa5cdb4ab67 706 {
Jonathan Austin 1:8aa5cdb4ab67 707 return MICROBIT_CANCELLED;
Jonathan Austin 1:8aa5cdb4ab67 708 }
Jonathan Austin 1:8aa5cdb4ab67 709
Jonathan Austin 1:8aa5cdb4ab67 710 return MICROBIT_OK;
Jonathan Austin 1:8aa5cdb4ab67 711 }
Jonathan Austin 1:8aa5cdb4ab67 712
Jonathan Austin 1:8aa5cdb4ab67 713 /**
Jonathan Austin 1:8aa5cdb4ab67 714 * Scrolls the given string to the display, from right to left.
Jonathan Austin 1:8aa5cdb4ab67 715 * Returns immediately, and executes the animation asynchronously.
Jonathan Austin 1:8aa5cdb4ab67 716 *
Jonathan Austin 1:8aa5cdb4ab67 717 * @param s The string to display.
Jonathan Austin 1:8aa5cdb4ab67 718 *
Jonathan Austin 1:8aa5cdb4ab67 719 * @param delay The time to delay between characters, in milliseconds. Defaults
Jonathan Austin 1:8aa5cdb4ab67 720 * to: MICROBIT_DEFAULT_SCROLL_SPEED.
Jonathan Austin 1:8aa5cdb4ab67 721 *
Jonathan Austin 1:8aa5cdb4ab67 722 * @return MICROBIT_OK, MICROBIT_BUSY if the display is already in use, or MICROBIT_INVALID_PARAMETER.
Jonathan Austin 1:8aa5cdb4ab67 723 *
Jonathan Austin 1:8aa5cdb4ab67 724 * @code
Jonathan Austin 1:8aa5cdb4ab67 725 * display.scrollAsync("abc123",100);
Jonathan Austin 1:8aa5cdb4ab67 726 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 727 */
Jonathan Austin 1:8aa5cdb4ab67 728 int MicroBitDisplay::scrollAsync(ManagedString s, int delay)
Jonathan Austin 1:8aa5cdb4ab67 729 {
Jonathan Austin 1:8aa5cdb4ab67 730 //sanitise this value
Jonathan Austin 1:8aa5cdb4ab67 731 if(delay <= 0)
Jonathan Austin 1:8aa5cdb4ab67 732 return MICROBIT_INVALID_PARAMETER;
Jonathan Austin 1:8aa5cdb4ab67 733
Jonathan Austin 1:8aa5cdb4ab67 734 // If the display is free, it's our turn to display.
Jonathan Austin 1:8aa5cdb4ab67 735 if (animationMode == ANIMATION_MODE_NONE || animationMode == ANIMATION_MODE_STOPPED)
Jonathan Austin 1:8aa5cdb4ab67 736 {
Jonathan Austin 1:8aa5cdb4ab67 737 scrollingPosition = width-1;
Jonathan Austin 1:8aa5cdb4ab67 738 scrollingChar = 0;
Jonathan Austin 1:8aa5cdb4ab67 739 scrollingText = s;
Jonathan Austin 1:8aa5cdb4ab67 740
Jonathan Austin 1:8aa5cdb4ab67 741 animationDelay = delay;
Jonathan Austin 1:8aa5cdb4ab67 742 animationTick = 0;
Jonathan Austin 1:8aa5cdb4ab67 743 animationMode = ANIMATION_MODE_SCROLL_TEXT;
Jonathan Austin 1:8aa5cdb4ab67 744 }
Jonathan Austin 1:8aa5cdb4ab67 745 else
Jonathan Austin 1:8aa5cdb4ab67 746 {
Jonathan Austin 1:8aa5cdb4ab67 747 return MICROBIT_BUSY;
Jonathan Austin 1:8aa5cdb4ab67 748 }
Jonathan Austin 1:8aa5cdb4ab67 749
Jonathan Austin 1:8aa5cdb4ab67 750 return MICROBIT_OK;
Jonathan Austin 1:8aa5cdb4ab67 751 }
Jonathan Austin 1:8aa5cdb4ab67 752
Jonathan Austin 1:8aa5cdb4ab67 753 /**
Jonathan Austin 1:8aa5cdb4ab67 754 * Scrolls the given image across the display, from right to left.
Jonathan Austin 1:8aa5cdb4ab67 755 * Returns immediately, and executes the animation asynchronously.
Jonathan Austin 1:8aa5cdb4ab67 756 *
Jonathan Austin 1:8aa5cdb4ab67 757 * @param image The image to display.
Jonathan Austin 1:8aa5cdb4ab67 758 *
Jonathan Austin 1:8aa5cdb4ab67 759 * @param delay The time between updates, in milliseconds. Defaults
Jonathan Austin 1:8aa5cdb4ab67 760 * to: MICROBIT_DEFAULT_SCROLL_SPEED.
Jonathan Austin 1:8aa5cdb4ab67 761 *
Jonathan Austin 1:8aa5cdb4ab67 762 * @param stride The number of pixels to shift by in each update. Defaults to MICROBIT_DEFAULT_SCROLL_STRIDE.
Jonathan Austin 1:8aa5cdb4ab67 763 *
Jonathan Austin 1:8aa5cdb4ab67 764 * @return MICROBIT_OK, MICROBIT_BUSY if the display is already in use, or MICROBIT_INVALID_PARAMETER.
Jonathan Austin 1:8aa5cdb4ab67 765 *
Jonathan Austin 1:8aa5cdb4ab67 766 * @code
Jonathan Austin 1:8aa5cdb4ab67 767 * MicrobitImage i("1,1,1,1,1\n1,1,1,1,1\n");
Jonathan Austin 1:8aa5cdb4ab67 768 * display.scrollAsync(i,100,1);
Jonathan Austin 1:8aa5cdb4ab67 769 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 770 */
Jonathan Austin 1:8aa5cdb4ab67 771 int MicroBitDisplay::scrollAsync(MicroBitImage image, int delay, int stride)
Jonathan Austin 1:8aa5cdb4ab67 772 {
Jonathan Austin 1:8aa5cdb4ab67 773 //sanitise the delay value
Jonathan Austin 1:8aa5cdb4ab67 774 if(delay <= 0)
Jonathan Austin 1:8aa5cdb4ab67 775 return MICROBIT_INVALID_PARAMETER;
Jonathan Austin 1:8aa5cdb4ab67 776
Jonathan Austin 1:8aa5cdb4ab67 777 // If the display is free, it's our turn to display.
Jonathan Austin 1:8aa5cdb4ab67 778 if (animationMode == ANIMATION_MODE_NONE || animationMode == ANIMATION_MODE_STOPPED)
Jonathan Austin 1:8aa5cdb4ab67 779 {
Jonathan Austin 1:8aa5cdb4ab67 780 scrollingImagePosition = stride < 0 ? width : -image.getWidth();
Jonathan Austin 1:8aa5cdb4ab67 781 scrollingImageStride = stride;
Jonathan Austin 1:8aa5cdb4ab67 782 scrollingImage = image;
Jonathan Austin 1:8aa5cdb4ab67 783 scrollingImageRendered = false;
Jonathan Austin 1:8aa5cdb4ab67 784
Jonathan Austin 1:8aa5cdb4ab67 785 animationDelay = stride == 0 ? 0 : delay;
Jonathan Austin 1:8aa5cdb4ab67 786 animationTick = 0;
Jonathan Austin 1:8aa5cdb4ab67 787 animationMode = ANIMATION_MODE_SCROLL_IMAGE;
Jonathan Austin 1:8aa5cdb4ab67 788 }
Jonathan Austin 1:8aa5cdb4ab67 789 else
Jonathan Austin 1:8aa5cdb4ab67 790 {
Jonathan Austin 1:8aa5cdb4ab67 791 return MICROBIT_BUSY;
Jonathan Austin 1:8aa5cdb4ab67 792 }
Jonathan Austin 1:8aa5cdb4ab67 793
Jonathan Austin 1:8aa5cdb4ab67 794 return MICROBIT_OK;
Jonathan Austin 1:8aa5cdb4ab67 795 }
Jonathan Austin 1:8aa5cdb4ab67 796
Jonathan Austin 1:8aa5cdb4ab67 797 /**
Jonathan Austin 1:8aa5cdb4ab67 798 * Scrolls the given string across the display, from right to left.
Jonathan Austin 1:8aa5cdb4ab67 799 * Blocks the calling thread until all text has been displayed.
Jonathan Austin 1:8aa5cdb4ab67 800 *
Jonathan Austin 1:8aa5cdb4ab67 801 * @param s The string to display.
Jonathan Austin 1:8aa5cdb4ab67 802 *
Jonathan Austin 1:8aa5cdb4ab67 803 * @param delay The time to delay between characters, in milliseconds. Defaults
Jonathan Austin 1:8aa5cdb4ab67 804 * to: MICROBIT_DEFAULT_SCROLL_SPEED.
Jonathan Austin 1:8aa5cdb4ab67 805 *
Jonathan Austin 1:8aa5cdb4ab67 806 * @return MICROBIT_OK, MICROBIT_CANCELLED or MICROBIT_INVALID_PARAMETER.
Jonathan Austin 1:8aa5cdb4ab67 807 *
Jonathan Austin 1:8aa5cdb4ab67 808 * @code
Jonathan Austin 1:8aa5cdb4ab67 809 * display.scroll("abc123",100);
Jonathan Austin 1:8aa5cdb4ab67 810 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 811 */
Jonathan Austin 1:8aa5cdb4ab67 812 int MicroBitDisplay::scroll(ManagedString s, int delay)
Jonathan Austin 1:8aa5cdb4ab67 813 {
Jonathan Austin 1:8aa5cdb4ab67 814 //sanitise this value
Jonathan Austin 1:8aa5cdb4ab67 815 if(delay <= 0)
Jonathan Austin 1:8aa5cdb4ab67 816 return MICROBIT_INVALID_PARAMETER;
Jonathan Austin 1:8aa5cdb4ab67 817
Jonathan Austin 1:8aa5cdb4ab67 818 // If there's an ongoing animation, wait for our turn to display.
Jonathan Austin 1:8aa5cdb4ab67 819 this->waitForFreeDisplay();
Jonathan Austin 1:8aa5cdb4ab67 820
Jonathan Austin 1:8aa5cdb4ab67 821 // If the display is free, it's our turn to display.
Jonathan Austin 1:8aa5cdb4ab67 822 // If someone called stopAnimation(), then we simply skip...
Jonathan Austin 1:8aa5cdb4ab67 823 if (animationMode == ANIMATION_MODE_NONE)
Jonathan Austin 1:8aa5cdb4ab67 824 {
Jonathan Austin 1:8aa5cdb4ab67 825 // Start the effect.
Jonathan Austin 1:8aa5cdb4ab67 826 this->scrollAsync(s, delay);
Jonathan Austin 1:8aa5cdb4ab67 827
Jonathan Austin 1:8aa5cdb4ab67 828 // Wait for completion.
Jonathan Austin 1:8aa5cdb4ab67 829 fiberWait();
Jonathan Austin 1:8aa5cdb4ab67 830 }
Jonathan Austin 1:8aa5cdb4ab67 831 else
Jonathan Austin 1:8aa5cdb4ab67 832 {
Jonathan Austin 1:8aa5cdb4ab67 833 return MICROBIT_CANCELLED;
Jonathan Austin 1:8aa5cdb4ab67 834 }
Jonathan Austin 1:8aa5cdb4ab67 835
Jonathan Austin 1:8aa5cdb4ab67 836 return MICROBIT_OK;
Jonathan Austin 1:8aa5cdb4ab67 837 }
Jonathan Austin 1:8aa5cdb4ab67 838
Jonathan Austin 1:8aa5cdb4ab67 839 /**
Jonathan Austin 1:8aa5cdb4ab67 840 * Scrolls the given image across the display, from right to left.
Jonathan Austin 1:8aa5cdb4ab67 841 * Blocks the calling thread until all the text has been displayed.
Jonathan Austin 1:8aa5cdb4ab67 842 *
Jonathan Austin 1:8aa5cdb4ab67 843 * @param image The image to display.
Jonathan Austin 1:8aa5cdb4ab67 844 *
Jonathan Austin 1:8aa5cdb4ab67 845 * @param delay The time between updates, in milliseconds. Defaults
Jonathan Austin 1:8aa5cdb4ab67 846 * to: MICROBIT_DEFAULT_SCROLL_SPEED.
Jonathan Austin 1:8aa5cdb4ab67 847 *
Jonathan Austin 1:8aa5cdb4ab67 848 * @param stride The number of pixels to shift by in each update. Defaults to MICROBIT_DEFAULT_SCROLL_STRIDE.
Jonathan Austin 1:8aa5cdb4ab67 849 *
Jonathan Austin 1:8aa5cdb4ab67 850 * @return MICROBIT_OK, MICROBIT_CANCELLED or MICROBIT_INVALID_PARAMETER.
Jonathan Austin 1:8aa5cdb4ab67 851 *
Jonathan Austin 1:8aa5cdb4ab67 852 * @code
Jonathan Austin 1:8aa5cdb4ab67 853 * MicrobitImage i("1,1,1,1,1\n1,1,1,1,1\n");
Jonathan Austin 1:8aa5cdb4ab67 854 * display.scroll(i,100,1);
Jonathan Austin 1:8aa5cdb4ab67 855 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 856 */
Jonathan Austin 1:8aa5cdb4ab67 857 int MicroBitDisplay::scroll(MicroBitImage image, int delay, int stride)
Jonathan Austin 1:8aa5cdb4ab67 858 {
Jonathan Austin 1:8aa5cdb4ab67 859 //sanitise the delay value
Jonathan Austin 1:8aa5cdb4ab67 860 if(delay <= 0)
Jonathan Austin 1:8aa5cdb4ab67 861 return MICROBIT_INVALID_PARAMETER;
Jonathan Austin 1:8aa5cdb4ab67 862
Jonathan Austin 1:8aa5cdb4ab67 863 // If there's an ongoing animation, wait for our turn to display.
Jonathan Austin 1:8aa5cdb4ab67 864 this->waitForFreeDisplay();
Jonathan Austin 1:8aa5cdb4ab67 865
Jonathan Austin 1:8aa5cdb4ab67 866 // If the display is free, it's our turn to display.
Jonathan Austin 1:8aa5cdb4ab67 867 // If someone called stopAnimation(), then we simply skip...
Jonathan Austin 1:8aa5cdb4ab67 868 if (animationMode == ANIMATION_MODE_NONE)
Jonathan Austin 1:8aa5cdb4ab67 869 {
Jonathan Austin 1:8aa5cdb4ab67 870 // Start the effect.
Jonathan Austin 1:8aa5cdb4ab67 871 this->scrollAsync(image, delay, stride);
Jonathan Austin 1:8aa5cdb4ab67 872
Jonathan Austin 1:8aa5cdb4ab67 873 // Wait for completion.
Jonathan Austin 1:8aa5cdb4ab67 874 fiberWait();
Jonathan Austin 1:8aa5cdb4ab67 875 }
Jonathan Austin 1:8aa5cdb4ab67 876 else
Jonathan Austin 1:8aa5cdb4ab67 877 {
Jonathan Austin 1:8aa5cdb4ab67 878 return MICROBIT_CANCELLED;
Jonathan Austin 1:8aa5cdb4ab67 879 }
Jonathan Austin 1:8aa5cdb4ab67 880
Jonathan Austin 1:8aa5cdb4ab67 881 return MICROBIT_OK;
Jonathan Austin 1:8aa5cdb4ab67 882 }
Jonathan Austin 1:8aa5cdb4ab67 883
Jonathan Austin 1:8aa5cdb4ab67 884 /**
Jonathan Austin 1:8aa5cdb4ab67 885 * "Animates" the current image across the display with a given stride, finishing on the last frame of the animation.
Jonathan Austin 1:8aa5cdb4ab67 886 * Returns immediately.
Jonathan Austin 1:8aa5cdb4ab67 887 *
Jonathan Austin 1:8aa5cdb4ab67 888 * @param image The image to display.
Jonathan Austin 1:8aa5cdb4ab67 889 *
Jonathan Austin 1:8aa5cdb4ab67 890 * @param delay The time to delay between each update of the display, in milliseconds.
Jonathan Austin 1:8aa5cdb4ab67 891 *
Jonathan Austin 1:8aa5cdb4ab67 892 * @param stride The number of pixels to shift by in each update.
Jonathan Austin 1:8aa5cdb4ab67 893 *
Jonathan Austin 1:8aa5cdb4ab67 894 * @param startingPosition the starting position on the display for the animation
Jonathan Austin 1:8aa5cdb4ab67 895 * to begin at. Defaults to MICROBIT_DISPLAY_ANIMATE_DEFAULT_POS.
Jonathan Austin 1:8aa5cdb4ab67 896 *
LancasterUniversity 22:23d7b9a4b082 897 * @param autoClear defines whether or not the display is automatically cleared once the animation is complete. By default, the display is cleared. Set this parameter to zero to disable the autoClear operation.
LancasterUniversity 22:23d7b9a4b082 898 *
Jonathan Austin 1:8aa5cdb4ab67 899 * @return MICROBIT_OK, MICROBIT_BUSY if the screen is in use, or MICROBIT_INVALID_PARAMETER.
Jonathan Austin 1:8aa5cdb4ab67 900 *
Jonathan Austin 1:8aa5cdb4ab67 901 * @code
Jonathan Austin 1:8aa5cdb4ab67 902 * const int heart_w = 10;
Jonathan Austin 1:8aa5cdb4ab67 903 * const int heart_h = 5;
Jonathan Austin 1:8aa5cdb4ab67 904 * 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 905 *
Jonathan Austin 1:8aa5cdb4ab67 906 * MicroBitImage i(heart_w,heart_h,heart);
Jonathan Austin 1:8aa5cdb4ab67 907 * display.animateAsync(i,100,5);
Jonathan Austin 1:8aa5cdb4ab67 908 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 909 */
LancasterUniversity 22:23d7b9a4b082 910 int MicroBitDisplay::animateAsync(MicroBitImage image, int delay, int stride, int startingPosition, int autoClear)
Jonathan Austin 1:8aa5cdb4ab67 911 {
Jonathan Austin 1:8aa5cdb4ab67 912 //sanitise the delay value
Jonathan Austin 1:8aa5cdb4ab67 913 if(delay <= 0)
Jonathan Austin 1:8aa5cdb4ab67 914 return MICROBIT_INVALID_PARAMETER;
Jonathan Austin 1:8aa5cdb4ab67 915
Jonathan Austin 1:8aa5cdb4ab67 916 // If the display is free, we can display.
Jonathan Austin 1:8aa5cdb4ab67 917 if (animationMode == ANIMATION_MODE_NONE || animationMode == ANIMATION_MODE_STOPPED)
Jonathan Austin 1:8aa5cdb4ab67 918 {
Jonathan Austin 1:8aa5cdb4ab67 919 // Assume right to left functionality, to align with scrollString()
Jonathan Austin 1:8aa5cdb4ab67 920 stride = -stride;
Jonathan Austin 1:8aa5cdb4ab67 921
Jonathan Austin 1:8aa5cdb4ab67 922 //calculate starting position which is offset by the stride
Jonathan Austin 1:8aa5cdb4ab67 923 scrollingImagePosition = (startingPosition == MICROBIT_DISPLAY_ANIMATE_DEFAULT_POS) ? MICROBIT_DISPLAY_WIDTH + stride : startingPosition;
Jonathan Austin 1:8aa5cdb4ab67 924 scrollingImageStride = stride;
Jonathan Austin 1:8aa5cdb4ab67 925 scrollingImage = image;
Jonathan Austin 1:8aa5cdb4ab67 926 scrollingImageRendered = false;
Jonathan Austin 1:8aa5cdb4ab67 927
Jonathan Austin 1:8aa5cdb4ab67 928 animationDelay = stride == 0 ? 0 : delay;
Jonathan Austin 1:8aa5cdb4ab67 929 animationTick = delay-1;
LancasterUniversity 22:23d7b9a4b082 930 animationMode = autoClear ? ANIMATION_MODE_ANIMATE_IMAGE_WITH_CLEAR : ANIMATION_MODE_ANIMATE_IMAGE;
Jonathan Austin 1:8aa5cdb4ab67 931 }
Jonathan Austin 1:8aa5cdb4ab67 932 else
Jonathan Austin 1:8aa5cdb4ab67 933 {
Jonathan Austin 1:8aa5cdb4ab67 934 return MICROBIT_BUSY;
Jonathan Austin 1:8aa5cdb4ab67 935 }
Jonathan Austin 1:8aa5cdb4ab67 936
Jonathan Austin 1:8aa5cdb4ab67 937 return MICROBIT_OK;
Jonathan Austin 1:8aa5cdb4ab67 938 }
Jonathan Austin 1:8aa5cdb4ab67 939
Jonathan Austin 1:8aa5cdb4ab67 940 /**
Jonathan Austin 1:8aa5cdb4ab67 941 * "Animates" the current image across the display with a given stride, finishing on the last frame of the animation.
Jonathan Austin 1:8aa5cdb4ab67 942 * Blocks the calling thread until the animation is complete.
Jonathan Austin 1:8aa5cdb4ab67 943 *
Jonathan Austin 1:8aa5cdb4ab67 944 *
Jonathan Austin 1:8aa5cdb4ab67 945 * @param delay The time to delay between each update of the display, in milliseconds.
Jonathan Austin 1:8aa5cdb4ab67 946 *
Jonathan Austin 1:8aa5cdb4ab67 947 * @param stride The number of pixels to shift by in each update.
Jonathan Austin 1:8aa5cdb4ab67 948 *
Jonathan Austin 1:8aa5cdb4ab67 949 * @param startingPosition the starting position on the display for the animation
Jonathan Austin 1:8aa5cdb4ab67 950 * to begin at. Defaults to MICROBIT_DISPLAY_ANIMATE_DEFAULT_POS.
Jonathan Austin 1:8aa5cdb4ab67 951 *
LancasterUniversity 22:23d7b9a4b082 952 * @param autoClear defines whether or not the display is automatically cleared once the animation is complete. By default, the display is cleared. Set this parameter to zero to disable the autoClear operation.
LancasterUniversity 22:23d7b9a4b082 953 *
Jonathan Austin 1:8aa5cdb4ab67 954 * @return MICROBIT_OK, MICROBIT_CANCELLED or MICROBIT_INVALID_PARAMETER.
Jonathan Austin 1:8aa5cdb4ab67 955 *
Jonathan Austin 1:8aa5cdb4ab67 956 * @code
Jonathan Austin 1:8aa5cdb4ab67 957 * const int heart_w = 10;
Jonathan Austin 1:8aa5cdb4ab67 958 * const int heart_h = 5;
Jonathan Austin 1:8aa5cdb4ab67 959 * 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 960 *
Jonathan Austin 1:8aa5cdb4ab67 961 * MicroBitImage i(heart_w,heart_h,heart);
Jonathan Austin 1:8aa5cdb4ab67 962 * display.animate(i,100,5);
Jonathan Austin 1:8aa5cdb4ab67 963 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 964 */
LancasterUniversity 22:23d7b9a4b082 965 int MicroBitDisplay::animate(MicroBitImage image, int delay, int stride, int startingPosition, int autoClear)
Jonathan Austin 1:8aa5cdb4ab67 966 {
Jonathan Austin 1:8aa5cdb4ab67 967 //sanitise the delay value
Jonathan Austin 1:8aa5cdb4ab67 968 if(delay <= 0)
Jonathan Austin 1:8aa5cdb4ab67 969 return MICROBIT_INVALID_PARAMETER;
Jonathan Austin 1:8aa5cdb4ab67 970
Jonathan Austin 1:8aa5cdb4ab67 971 // If there's an ongoing animation, wait for our turn to display.
Jonathan Austin 1:8aa5cdb4ab67 972 this->waitForFreeDisplay();
Jonathan Austin 1:8aa5cdb4ab67 973
Jonathan Austin 1:8aa5cdb4ab67 974 // If the display is free, it's our turn to display.
Jonathan Austin 1:8aa5cdb4ab67 975 // If someone called stopAnimation(), then we simply skip...
Jonathan Austin 1:8aa5cdb4ab67 976 if (animationMode == ANIMATION_MODE_NONE)
Jonathan Austin 1:8aa5cdb4ab67 977 {
Jonathan Austin 1:8aa5cdb4ab67 978 // Start the effect.
LancasterUniversity 22:23d7b9a4b082 979 this->animateAsync(image, delay, stride, startingPosition, autoClear);
Jonathan Austin 1:8aa5cdb4ab67 980
Jonathan Austin 1:8aa5cdb4ab67 981 // Wait for completion.
Jonathan Austin 1:8aa5cdb4ab67 982 //TODO: Put this in when we merge tight-validation
Jonathan Austin 1:8aa5cdb4ab67 983 //if (delay > 0)
Jonathan Austin 1:8aa5cdb4ab67 984 fiberWait();
Jonathan Austin 1:8aa5cdb4ab67 985 }
Jonathan Austin 1:8aa5cdb4ab67 986 else
Jonathan Austin 1:8aa5cdb4ab67 987 {
Jonathan Austin 1:8aa5cdb4ab67 988 return MICROBIT_CANCELLED;
Jonathan Austin 1:8aa5cdb4ab67 989 }
Jonathan Austin 1:8aa5cdb4ab67 990
Jonathan Austin 1:8aa5cdb4ab67 991 return MICROBIT_OK;
Jonathan Austin 1:8aa5cdb4ab67 992 }
Jonathan Austin 1:8aa5cdb4ab67 993
Jonathan Austin 1:8aa5cdb4ab67 994
Jonathan Austin 1:8aa5cdb4ab67 995 /**
Jonathan Austin 1:8aa5cdb4ab67 996 * Configures the brightness of the display.
Jonathan Austin 1:8aa5cdb4ab67 997 *
Jonathan Austin 1:8aa5cdb4ab67 998 * @param b The brightness to set the brightness to, in the range 0 - 255.
Jonathan Austin 1:8aa5cdb4ab67 999 *
Jonathan Austin 1:8aa5cdb4ab67 1000 * @return MICROBIT_OK, or MICROBIT_INVALID_PARAMETER
Jonathan Austin 1:8aa5cdb4ab67 1001 *
Jonathan Austin 1:8aa5cdb4ab67 1002 * @code
Jonathan Austin 1:8aa5cdb4ab67 1003 * display.setBrightness(255); //max brightness
Jonathan Austin 1:8aa5cdb4ab67 1004 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 1005 */
Jonathan Austin 1:8aa5cdb4ab67 1006 int MicroBitDisplay::setBrightness(int b)
Jonathan Austin 1:8aa5cdb4ab67 1007 {
Jonathan Austin 1:8aa5cdb4ab67 1008 //sanitise the brightness level
Jonathan Austin 1:8aa5cdb4ab67 1009 if(b < 0 || b > 255)
Jonathan Austin 1:8aa5cdb4ab67 1010 return MICROBIT_INVALID_PARAMETER;
Jonathan Austin 1:8aa5cdb4ab67 1011
Jonathan Austin 1:8aa5cdb4ab67 1012 this->brightness = b;
Jonathan Austin 1:8aa5cdb4ab67 1013
Jonathan Austin 1:8aa5cdb4ab67 1014 return MICROBIT_OK;
Jonathan Austin 1:8aa5cdb4ab67 1015 }
Jonathan Austin 1:8aa5cdb4ab67 1016
Jonathan Austin 1:8aa5cdb4ab67 1017 /**
Jonathan Austin 1:8aa5cdb4ab67 1018 * Configures the mode of the display.
Jonathan Austin 1:8aa5cdb4ab67 1019 *
Jonathan Austin 1:8aa5cdb4ab67 1020 * @param mode The mode to swap the display into. One of: DISPLAY_MODE_GREYSCALE,
Jonathan Austin 1:8aa5cdb4ab67 1021 * DISPLAY_MODE_BLACK_AND_WHITE, DISPLAY_MODE_BLACK_AND_WHITE_LIGHT_SENSE
Jonathan Austin 1:8aa5cdb4ab67 1022 *
Jonathan Austin 1:8aa5cdb4ab67 1023 * @code
Jonathan Austin 1:8aa5cdb4ab67 1024 * display.setDisplayMode(DISPLAY_MODE_GREYSCALE); //per pixel brightness
Jonathan Austin 1:8aa5cdb4ab67 1025 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 1026 */
Jonathan Austin 1:8aa5cdb4ab67 1027 void MicroBitDisplay::setDisplayMode(DisplayMode mode)
Jonathan Austin 1:8aa5cdb4ab67 1028 {
Jonathan Austin 1:8aa5cdb4ab67 1029 if(mode == DISPLAY_MODE_BLACK_AND_WHITE_LIGHT_SENSE)
Jonathan Austin 1:8aa5cdb4ab67 1030 {
Jonathan Austin 1:8aa5cdb4ab67 1031 //to reduce the artifacts on the display - increase the tick
Jonathan Austin 1:8aa5cdb4ab67 1032 if(system_timer_get_period() != MICROBIT_LIGHT_SENSOR_TICK_PERIOD)
Jonathan Austin 1:8aa5cdb4ab67 1033 system_timer_set_period(MICROBIT_LIGHT_SENSOR_TICK_PERIOD);
Jonathan Austin 1:8aa5cdb4ab67 1034 }
Jonathan Austin 1:8aa5cdb4ab67 1035
Jonathan Austin 1:8aa5cdb4ab67 1036 if(this->mode == DISPLAY_MODE_BLACK_AND_WHITE_LIGHT_SENSE && mode != DISPLAY_MODE_BLACK_AND_WHITE_LIGHT_SENSE)
Jonathan Austin 1:8aa5cdb4ab67 1037 {
Jonathan Austin 1:8aa5cdb4ab67 1038 delete this->lightSensor;
Jonathan Austin 1:8aa5cdb4ab67 1039
Jonathan Austin 1:8aa5cdb4ab67 1040 this->lightSensor = NULL;
Jonathan Austin 1:8aa5cdb4ab67 1041 }
Jonathan Austin 1:8aa5cdb4ab67 1042
Jonathan Austin 1:8aa5cdb4ab67 1043 this->mode = mode;
Jonathan Austin 1:8aa5cdb4ab67 1044 }
Jonathan Austin 1:8aa5cdb4ab67 1045
Jonathan Austin 1:8aa5cdb4ab67 1046 /**
Jonathan Austin 1:8aa5cdb4ab67 1047 * Retrieves the mode of the display.
Jonathan Austin 1:8aa5cdb4ab67 1048 *
Jonathan Austin 1:8aa5cdb4ab67 1049 * @return the current mode of the display
Jonathan Austin 1:8aa5cdb4ab67 1050 */
Jonathan Austin 1:8aa5cdb4ab67 1051 int MicroBitDisplay::getDisplayMode()
Jonathan Austin 1:8aa5cdb4ab67 1052 {
Jonathan Austin 1:8aa5cdb4ab67 1053 return this->mode;
Jonathan Austin 1:8aa5cdb4ab67 1054 }
Jonathan Austin 1:8aa5cdb4ab67 1055
Jonathan Austin 1:8aa5cdb4ab67 1056 /**
Jonathan Austin 1:8aa5cdb4ab67 1057 * Fetches the current brightness of this display.
Jonathan Austin 1:8aa5cdb4ab67 1058 *
Jonathan Austin 1:8aa5cdb4ab67 1059 * @return the brightness of this display, in the range 0..255.
Jonathan Austin 1:8aa5cdb4ab67 1060 *
Jonathan Austin 1:8aa5cdb4ab67 1061 * @code
Jonathan Austin 1:8aa5cdb4ab67 1062 * display.getBrightness(); //the current brightness
Jonathan Austin 1:8aa5cdb4ab67 1063 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 1064 */
Jonathan Austin 1:8aa5cdb4ab67 1065 int MicroBitDisplay::getBrightness()
Jonathan Austin 1:8aa5cdb4ab67 1066 {
Jonathan Austin 1:8aa5cdb4ab67 1067 return this->brightness;
Jonathan Austin 1:8aa5cdb4ab67 1068 }
Jonathan Austin 1:8aa5cdb4ab67 1069
Jonathan Austin 1:8aa5cdb4ab67 1070 /**
Jonathan Austin 1:8aa5cdb4ab67 1071 * Rotates the display to the given position.
Jonathan Austin 1:8aa5cdb4ab67 1072 *
Jonathan Austin 1:8aa5cdb4ab67 1073 * Axis aligned values only.
Jonathan Austin 1:8aa5cdb4ab67 1074 *
Jonathan Austin 1:8aa5cdb4ab67 1075 * @code
Jonathan Austin 1:8aa5cdb4ab67 1076 * display.rotateTo(MICROBIT_DISPLAY_ROTATION_180); //rotates 180 degrees from original orientation
Jonathan Austin 1:8aa5cdb4ab67 1077 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 1078 */
Jonathan Austin 1:8aa5cdb4ab67 1079 void MicroBitDisplay::rotateTo(DisplayRotation rotation)
Jonathan Austin 1:8aa5cdb4ab67 1080 {
Jonathan Austin 1:8aa5cdb4ab67 1081 this->rotation = rotation;
Jonathan Austin 1:8aa5cdb4ab67 1082 }
Jonathan Austin 1:8aa5cdb4ab67 1083
Jonathan Austin 1:8aa5cdb4ab67 1084 /**
Jonathan Austin 1:8aa5cdb4ab67 1085 * Enables or disables the display entirely, and releases the pins for other uses.
Jonathan Austin 1:8aa5cdb4ab67 1086 *
Jonathan Austin 1:8aa5cdb4ab67 1087 * @param enableDisplay true to enabled the display, or false to disable it.
Jonathan Austin 1:8aa5cdb4ab67 1088 */
Jonathan Austin 1:8aa5cdb4ab67 1089 void MicroBitDisplay::setEnable(bool enableDisplay)
Jonathan Austin 1:8aa5cdb4ab67 1090 {
Jonathan Austin 1:8aa5cdb4ab67 1091 // If we're already in the correct state, then there's nothing to do.
Jonathan Austin 1:8aa5cdb4ab67 1092 if(((status & MICROBIT_COMPONENT_RUNNING) && enableDisplay) || (!(status & MICROBIT_COMPONENT_RUNNING) && !enableDisplay))
Jonathan Austin 1:8aa5cdb4ab67 1093 return;
Jonathan Austin 1:8aa5cdb4ab67 1094
Jonathan Austin 1:8aa5cdb4ab67 1095 uint32_t rmask = 0;
Jonathan Austin 1:8aa5cdb4ab67 1096 uint32_t cmask = 0;
Jonathan Austin 1:8aa5cdb4ab67 1097
Jonathan Austin 1:8aa5cdb4ab67 1098 for (int i = matrixMap.rowStart; i < matrixMap.rowStart + matrixMap.rows; i++)
Jonathan Austin 1:8aa5cdb4ab67 1099 rmask |= 0x01 << i;
Jonathan Austin 1:8aa5cdb4ab67 1100
Jonathan Austin 1:8aa5cdb4ab67 1101 for (int i = matrixMap.columnStart; i < matrixMap.columnStart + matrixMap.columns; i++)
Jonathan Austin 1:8aa5cdb4ab67 1102 cmask |= 0x01 << i;
Jonathan Austin 1:8aa5cdb4ab67 1103
Jonathan Austin 1:8aa5cdb4ab67 1104 if (enableDisplay)
Jonathan Austin 1:8aa5cdb4ab67 1105 {
Jonathan Austin 1:8aa5cdb4ab67 1106 PortOut p(Port0, rmask | cmask);
Jonathan Austin 1:8aa5cdb4ab67 1107 status |= MICROBIT_COMPONENT_RUNNING;
Jonathan Austin 1:8aa5cdb4ab67 1108 }
Jonathan Austin 1:8aa5cdb4ab67 1109 else
Jonathan Austin 1:8aa5cdb4ab67 1110 {
Jonathan Austin 1:8aa5cdb4ab67 1111 PortIn p(Port0, rmask | cmask);
Jonathan Austin 1:8aa5cdb4ab67 1112 p.mode(PullNone);
Jonathan Austin 1:8aa5cdb4ab67 1113 status &= ~MICROBIT_COMPONENT_RUNNING;
Jonathan Austin 1:8aa5cdb4ab67 1114 }
Jonathan Austin 1:8aa5cdb4ab67 1115 }
Jonathan Austin 1:8aa5cdb4ab67 1116
Jonathan Austin 1:8aa5cdb4ab67 1117 /**
Jonathan Austin 1:8aa5cdb4ab67 1118 * Enables the display, should only be called if the display is disabled.
Jonathan Austin 1:8aa5cdb4ab67 1119 *
Jonathan Austin 1:8aa5cdb4ab67 1120 * @code
Jonathan Austin 1:8aa5cdb4ab67 1121 * display.enable(); //Enables the display mechanics
Jonathan Austin 1:8aa5cdb4ab67 1122 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 1123 *
Jonathan Austin 1:8aa5cdb4ab67 1124 * @note Only enables the display if the display is currently disabled.
Jonathan Austin 1:8aa5cdb4ab67 1125 */
Jonathan Austin 1:8aa5cdb4ab67 1126 void MicroBitDisplay::enable()
Jonathan Austin 1:8aa5cdb4ab67 1127 {
Jonathan Austin 1:8aa5cdb4ab67 1128 setEnable(true);
Jonathan Austin 1:8aa5cdb4ab67 1129 }
Jonathan Austin 1:8aa5cdb4ab67 1130
Jonathan Austin 1:8aa5cdb4ab67 1131 /**
Jonathan Austin 1:8aa5cdb4ab67 1132 * Disables the display, which releases control of the GPIO pins used by the display,
Jonathan Austin 1:8aa5cdb4ab67 1133 * which are exposed on the edge connector.
Jonathan Austin 1:8aa5cdb4ab67 1134 *
Jonathan Austin 1:8aa5cdb4ab67 1135 * @code
Jonathan Austin 1:8aa5cdb4ab67 1136 * display.disable(); //disables the display
Jonathan Austin 1:8aa5cdb4ab67 1137 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 1138 *
Jonathan Austin 1:8aa5cdb4ab67 1139 * @note Only disables the display if the display is currently enabled.
Jonathan Austin 1:8aa5cdb4ab67 1140 */
Jonathan Austin 1:8aa5cdb4ab67 1141 void MicroBitDisplay::disable()
Jonathan Austin 1:8aa5cdb4ab67 1142 {
Jonathan Austin 1:8aa5cdb4ab67 1143 setEnable(false);
Jonathan Austin 1:8aa5cdb4ab67 1144 }
Jonathan Austin 1:8aa5cdb4ab67 1145
Jonathan Austin 1:8aa5cdb4ab67 1146 /**
Jonathan Austin 1:8aa5cdb4ab67 1147 * Clears the display of any remaining pixels.
Jonathan Austin 1:8aa5cdb4ab67 1148 *
Jonathan Austin 1:8aa5cdb4ab67 1149 * `display.image.clear()` can also be used!
Jonathan Austin 1:8aa5cdb4ab67 1150 *
Jonathan Austin 1:8aa5cdb4ab67 1151 * @code
Jonathan Austin 1:8aa5cdb4ab67 1152 * display.clear(); //clears the display
Jonathan Austin 1:8aa5cdb4ab67 1153 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 1154 */
Jonathan Austin 1:8aa5cdb4ab67 1155 void MicroBitDisplay::clear()
Jonathan Austin 1:8aa5cdb4ab67 1156 {
Jonathan Austin 1:8aa5cdb4ab67 1157 image.clear();
Jonathan Austin 1:8aa5cdb4ab67 1158 }
Jonathan Austin 1:8aa5cdb4ab67 1159
Jonathan Austin 1:8aa5cdb4ab67 1160 /**
Jonathan Austin 1:8aa5cdb4ab67 1161 * Updates the font that will be used for display operations.
Jonathan Austin 1:8aa5cdb4ab67 1162 *
Jonathan Austin 1:8aa5cdb4ab67 1163 * @param font the new font that will be used to render characters.
Jonathan Austin 1:8aa5cdb4ab67 1164 *
Jonathan Austin 1:8aa5cdb4ab67 1165 * @note DEPRECATED! Please use MicroBitFont::setSystemFont() instead.
Jonathan Austin 1:8aa5cdb4ab67 1166 */
Jonathan Austin 1:8aa5cdb4ab67 1167 void MicroBitDisplay::setFont(MicroBitFont font)
Jonathan Austin 1:8aa5cdb4ab67 1168 {
Jonathan Austin 1:8aa5cdb4ab67 1169 MicroBitFont::setSystemFont(font);
Jonathan Austin 1:8aa5cdb4ab67 1170 }
Jonathan Austin 1:8aa5cdb4ab67 1171
Jonathan Austin 1:8aa5cdb4ab67 1172 /**
Jonathan Austin 1:8aa5cdb4ab67 1173 * Retrieves the font object used for rendering characters on the display.
Jonathan Austin 1:8aa5cdb4ab67 1174 *
Jonathan Austin 1:8aa5cdb4ab67 1175 * @note DEPRECATED! Please use MicroBitFont::getSystemFont() instead.
Jonathan Austin 1:8aa5cdb4ab67 1176 */
Jonathan Austin 1:8aa5cdb4ab67 1177 MicroBitFont MicroBitDisplay::getFont()
Jonathan Austin 1:8aa5cdb4ab67 1178 {
Jonathan Austin 1:8aa5cdb4ab67 1179 return MicroBitFont::getSystemFont();
Jonathan Austin 1:8aa5cdb4ab67 1180 }
Jonathan Austin 1:8aa5cdb4ab67 1181
Jonathan Austin 1:8aa5cdb4ab67 1182 /**
Jonathan Austin 1:8aa5cdb4ab67 1183 * Captures the bitmap currently being rendered on the display.
Jonathan Austin 1:8aa5cdb4ab67 1184 *
Jonathan Austin 1:8aa5cdb4ab67 1185 * @return a MicroBitImage containing the captured data.
Jonathan Austin 1:8aa5cdb4ab67 1186 */
Jonathan Austin 1:8aa5cdb4ab67 1187 MicroBitImage MicroBitDisplay::screenShot()
Jonathan Austin 1:8aa5cdb4ab67 1188 {
Jonathan Austin 1:8aa5cdb4ab67 1189 return image.crop(0,0,MICROBIT_DISPLAY_WIDTH,MICROBIT_DISPLAY_HEIGHT);
Jonathan Austin 1:8aa5cdb4ab67 1190 }
Jonathan Austin 1:8aa5cdb4ab67 1191
Jonathan Austin 1:8aa5cdb4ab67 1192 /**
Jonathan Austin 1:8aa5cdb4ab67 1193 * Gives a representative figure of the light level in the current environment
Jonathan Austin 1:8aa5cdb4ab67 1194 * where are micro:bit is situated.
Jonathan Austin 1:8aa5cdb4ab67 1195 *
Jonathan Austin 1:8aa5cdb4ab67 1196 * Internally, it constructs an instance of a MicroBitLightSensor if not already configured
Jonathan Austin 1:8aa5cdb4ab67 1197 * and sets the display mode to DISPLAY_MODE_BLACK_AND_WHITE_LIGHT_SENSE.
Jonathan Austin 1:8aa5cdb4ab67 1198 *
Jonathan Austin 1:8aa5cdb4ab67 1199 * This also changes the tickPeriod to MICROBIT_LIGHT_SENSOR_TICK_SPEED so
Jonathan Austin 1:8aa5cdb4ab67 1200 * that the display does not suffer from artifacts.
Jonathan Austin 1:8aa5cdb4ab67 1201 *
Jonathan Austin 1:8aa5cdb4ab67 1202 * @return an indicative light level in the range 0 - 255.
Jonathan Austin 1:8aa5cdb4ab67 1203 *
Jonathan Austin 1:8aa5cdb4ab67 1204 * @note this will return 0 on the first call to this method, a light reading
Jonathan Austin 1:8aa5cdb4ab67 1205 * will be available after the display has activated the light sensor for the
Jonathan Austin 1:8aa5cdb4ab67 1206 * first time.
Jonathan Austin 1:8aa5cdb4ab67 1207 */
Jonathan Austin 1:8aa5cdb4ab67 1208 int MicroBitDisplay::readLightLevel()
Jonathan Austin 1:8aa5cdb4ab67 1209 {
Jonathan Austin 1:8aa5cdb4ab67 1210 if(mode != DISPLAY_MODE_BLACK_AND_WHITE_LIGHT_SENSE)
Jonathan Austin 1:8aa5cdb4ab67 1211 {
Jonathan Austin 1:8aa5cdb4ab67 1212 setDisplayMode(DISPLAY_MODE_BLACK_AND_WHITE_LIGHT_SENSE);
Jonathan Austin 1:8aa5cdb4ab67 1213 this->lightSensor = new MicroBitLightSensor(matrixMap);
Jonathan Austin 1:8aa5cdb4ab67 1214 }
Jonathan Austin 1:8aa5cdb4ab67 1215
Jonathan Austin 1:8aa5cdb4ab67 1216 return this->lightSensor->read();
Jonathan Austin 1:8aa5cdb4ab67 1217 }
Jonathan Austin 1:8aa5cdb4ab67 1218
Jonathan Austin 1:8aa5cdb4ab67 1219 /**
Jonathan Austin 1:8aa5cdb4ab67 1220 * Destructor for MicroBitDisplay, where we deregister this instance from the array of system components.
Jonathan Austin 1:8aa5cdb4ab67 1221 */
Jonathan Austin 1:8aa5cdb4ab67 1222 MicroBitDisplay::~MicroBitDisplay()
Jonathan Austin 1:8aa5cdb4ab67 1223 {
Jonathan Austin 1:8aa5cdb4ab67 1224 system_timer_remove_component(this);
LancasterUniversity 20:ad2a5c7debf4 1225 }