@@ -181,6 +181,7 @@ static const DisplayPoint display_map[COLUMN_COUNT][ROW_COUNT] = {
181
181
#define COLUMN_PINS_MASK 0x1ff0
182
182
#define MIN_ROW_PIN 13
183
183
#define MAX_ROW_PIN 15
184
+ #define ROW_PINS_MASK 0xe000
184
185
185
186
inline void microbit_display_obj_t::setPinsForRow (uint8_t brightness) {
186
187
if (brightness == 0 ) {
@@ -190,13 +191,39 @@ inline void microbit_display_obj_t::setPinsForRow(uint8_t brightness) {
190
191
}
191
192
}
192
193
194
+ /* This is the primary PWM driver/display driver. It will operate on one row
195
+ * (9 pins) per invocation. It will turn on LEDs with maximum brightness,
196
+ * then let the "callback" callback turn off the LEDs as appropriate for the
197
+ * required brightness level.
198
+ *
199
+ * For each row
200
+ * Turn off all the LEDs in the previous row
201
+ * Set the column bits high (off)
202
+ * Set the row strobe low (off)
203
+ * Turn on all the LEDs in the current row that have maximum brightness
204
+ * Set the row strobe high (on)
205
+ * Set some/all column bits low (on)
206
+ * Register the PWM callback
207
+ * For each callback start with brightness 0
208
+ * If brightness 0
209
+ * Turn off the LEDs specified at this level
210
+ * Else
211
+ * Turn on the LEDs specified at this level
212
+ * If brightness max
213
+ * Disable the PWM callback
214
+ * Else
215
+ * Re-queue the PWM callback after the appropriate delay
216
+ */
193
217
void microbit_display_obj_t::advanceRow () {
194
- // First, clear the old row.
218
+ /* Clear all of the column bits */
195
219
nrf_gpio_pins_set (COLUMN_PINS_MASK);
196
- // Clear the old bit pattern for this row.
220
+ /* Clear the strobe bit for this row */
197
221
nrf_gpio_pin_clear (strobe_row+MIN_ROW_PIN);
198
222
199
- // Move on to the next row.
223
+ /* Move to the next row. Before this, "this row" refers to the row
224
+ * manipulated by the previous invocation of this function. After this,
225
+ * "this row" refers to the row manipulated by the current invocation of
226
+ * this function. */
200
227
strobe_row++;
201
228
202
229
// Reset the row counts and bit mask when we have hit the max.
@@ -215,9 +242,9 @@ void microbit_display_obj_t::advanceRow() {
215
242
uint8_t brightness = microbit_display_obj.image_buffer [x][y];
216
243
pins_for_brightness[brightness] |= (1 <<(i+MIN_COLUMN_PIN));
217
244
}
218
- // Set pin for row
245
+ /* Enable the strobe bit for this row */
219
246
nrf_gpio_pin_set (strobe_row+MIN_ROW_PIN);
220
- // Turn on any pixels that are at max
247
+ /* Enable the column bits for all pins that need to be on. */
221
248
nrf_gpio_pins_clear (pins_for_brightness[MAX_BRIGHTNESS]);
222
249
}
223
250
@@ -238,6 +265,8 @@ static const uint16_t render_timings[] =
238
265
239
266
#define DISPLAY_TICKER_SLOT 1
240
267
268
+ /* This is the PWM callback. It is registered by the animation callback and
269
+ * will unregister itself when all of the brightness steps are complete. */
241
270
static int32_t callback (void ) {
242
271
microbit_display_obj_t *display = µbit_display_obj;
243
272
mp_uint_t brightness = display->previous_brightness ;
@@ -315,7 +344,13 @@ static void microbit_display_update(void) {
315
344
316
345
#define GREYSCALE_MASK ((1 <<MAX_BRIGHTNESS)-2 )
317
346
347
+ /* This is the top-level animation/display callback. It is not a registered
348
+ * callback. */
318
349
void microbit_display_tick (void ) {
350
+ /* Do nothing if the display is not active. */
351
+ if (!microbit_display_obj.active ) {
352
+ return ;
353
+ }
319
354
320
355
microbit_display_obj.advanceRow ();
321
356
@@ -377,6 +412,40 @@ mp_obj_t microbit_display_scroll_func(mp_uint_t n_args, const mp_obj_t *pos_args
377
412
}
378
413
MP_DEFINE_CONST_FUN_OBJ_KW (microbit_display_scroll_obj, 1 , microbit_display_scroll_func);
379
414
415
+ mp_obj_t microbit_display_on_func (mp_obj_t obj) {
416
+ microbit_display_obj_t *self = (microbit_display_obj_t *)obj;
417
+ /* Re-enable the display loop. This will resume any animations in
418
+ * progress and display any static image. */
419
+ self->active = true ;
420
+ return mp_const_none;
421
+ }
422
+ MP_DEFINE_CONST_FUN_OBJ_1 (microbit_display_on_obj, microbit_display_on_func);
423
+
424
+ mp_obj_t microbit_display_off_func (mp_obj_t obj) {
425
+ microbit_display_obj_t *self = (microbit_display_obj_t *)obj;
426
+ /* Disable the display loop. This will pause any animations in progress.
427
+ * It will not prevent a user from attempting to modify the state, but
428
+ * modifications will not appear to have any effect until the display loop
429
+ * is re-enabled. */
430
+ self->active = false ;
431
+ /* Disable the row strobes, allowing the columns to be used freely for
432
+ * GPIO. */
433
+ nrf_gpio_pins_clear (ROW_PINS_MASK);
434
+ return mp_const_none;
435
+ }
436
+ MP_DEFINE_CONST_FUN_OBJ_1 (microbit_display_off_obj, microbit_display_off_func);
437
+
438
+ mp_obj_t microbit_display_is_on_func (mp_obj_t obj) {
439
+ microbit_display_obj_t *self = (microbit_display_obj_t *)obj;
440
+ if (self->active ) {
441
+ return mp_const_true;
442
+ }
443
+ else {
444
+ return mp_const_false;
445
+ }
446
+ }
447
+ MP_DEFINE_CONST_FUN_OBJ_1 (microbit_display_is_on_obj, microbit_display_is_on_func);
448
+
380
449
void microbit_display_clear (void ) {
381
450
// Reset repeat state, cancel animation and clear screen.
382
451
wakeup_event = false ;
@@ -430,6 +499,9 @@ STATIC const mp_map_elem_t microbit_display_locals_dict_table[] = {
430
499
{ MP_OBJ_NEW_QSTR (MP_QSTR_show), (mp_obj_t )µbit_display_show_obj },
431
500
{ MP_OBJ_NEW_QSTR (MP_QSTR_scroll), (mp_obj_t )µbit_display_scroll_obj },
432
501
{ MP_OBJ_NEW_QSTR (MP_QSTR_clear), (mp_obj_t )µbit_display_clear_obj },
502
+ { MP_OBJ_NEW_QSTR (MP_QSTR_on), (mp_obj_t )µbit_display_on_obj },
503
+ { MP_OBJ_NEW_QSTR (MP_QSTR_off), (mp_obj_t )µbit_display_off_obj },
504
+ { MP_OBJ_NEW_QSTR (MP_QSTR_is_on), (mp_obj_t )µbit_display_is_on_obj },
433
505
};
434
506
435
507
STATIC MP_DEFINE_CONST_DICT (microbit_display_locals_dict, microbit_display_locals_dict_table);
@@ -456,6 +528,7 @@ microbit_display_obj_t microbit_display_obj = {
456
528
{µbit_display_type},
457
529
{ 0 },
458
530
.previous_brightness = 0 ,
531
+ .active = 1 ,
459
532
.strobe_row = 0 ,
460
533
.brightnesses = 0 ,
461
534
.pins_for_brightness = { 0 },
0 commit comments