@@ -61,11 +61,11 @@ void microbit_display_print(microbit_display_obj_t *display, microbit_image_obj_
61
61
}
62
62
63
63
mp_obj_t microbit_display_print_func (mp_uint_t n_args, const mp_obj_t *args) {
64
- // TODO support async mode
64
+ // TODO: Support async mode.
65
65
66
66
microbit_display_obj_t *self = (microbit_display_obj_t *)args[0 ];
67
67
68
- // cancel any animations
68
+ // Cancel any animations.
69
69
MP_STATE_PORT (async_data)[0 ] = NULL ;
70
70
MP_STATE_PORT (async_data)[1 ] = NULL ;
71
71
MP_STATE_PORT (async_data)[2 ] = NULL ;
@@ -75,9 +75,9 @@ mp_obj_t microbit_display_print_func(mp_uint_t n_args, const mp_obj_t *args) {
75
75
mp_uint_t len;
76
76
const char *str = mp_obj_str_get_data (args[1 ], &len);
77
77
if (len == 0 ) {
78
- // no chars, do nothing
78
+ // There are no chars; do nothing.
79
79
} else if (len == 1 ) {
80
- // single char
80
+ // A single char; convert to an image and print that.
81
81
microbit_display_print (self, microbit_image_for_char (str[0 ]));
82
82
} else {
83
83
mp_int_t delay;
@@ -100,7 +100,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(microbit_display_print_obj, 2, 3, microbit_d
100
100
static uint8_t async_mode;
101
101
static mp_obj_t async_repeat_iterable = NULL ;
102
102
static mp_obj_t async_iterator = NULL ;
103
- /* Record if an error occurs in async animation -- Unfortunately there is no way to report this */
103
+ // Record if an error occurs in async animation. Unfortunately there is no way to report this.
104
104
static bool async_error = false ;
105
105
static uint16_t async_nonce = 0 ;
106
106
static mp_uint_t async_delay = 1000 ;
@@ -148,77 +148,69 @@ static const DisplayPoint display_map[MICROBIT_DISPLAY_COLUMN_COUNT][MICROBIT_DI
148
148
};
149
149
150
150
inline void microbit_display_obj_t::setPinsForRow (uint8_t brightness) {
151
-
152
151
int column_strobe = 0 ;
153
152
154
153
// Calculate the bitpattern to write.
155
- for (int i = 0 ; i<MICROBIT_DISPLAY_COLUMN_COUNT; i++)
156
- {
157
- if (row_brightness[i] >= brightness)
154
+ for (int i = 0 ; i < MICROBIT_DISPLAY_COLUMN_COUNT; i++) {
155
+ if (row_brightness[i] >= brightness) {
158
156
column_strobe |= (1 << i);
157
+ }
159
158
}
160
159
161
- // write the new bit pattern
162
- // set port 0 4-7 and retain lower 4 bits
160
+ // Wwrite the new bit pattern.
161
+ // Set port 0 4-7 and retain lower 4 bits.
163
162
nrf_gpio_port_write (NRF_GPIO_PORT_SELECT_PORT0, ~column_strobe<<4 & 0xF0 | nrf_gpio_port_read (NRF_GPIO_PORT_SELECT_PORT0) & 0x0F );
164
163
165
- // set port 1 8-12 for the current row
164
+ // Set port 1 8-12 for the current row.
166
165
nrf_gpio_port_write (NRF_GPIO_PORT_SELECT_PORT1, strobe_mask | (~column_strobe>>4 & 0x1F ));
167
-
168
166
}
169
167
170
168
void microbit_display_obj_t::advanceRow () {
169
+ // First, clear the old row.
171
170
172
- /* Clear the old row */
173
-
174
- // clear the old bit pattern for this row.
175
- // clear port 0 4-7 and retain lower 4 bits
171
+ // Clear the old bit pattern for this row.
172
+ // Clear port 0 4-7 and retain lower 4 bits.
176
173
nrf_gpio_port_write (NRF_GPIO_PORT_SELECT_PORT0, 0xF0 | nrf_gpio_port_read (NRF_GPIO_PORT_SELECT_PORT0) & 0x0F );
177
-
178
- // clear port 1 8-12 for the current row
174
+ // Clear port 1 8-12 for the current row.
179
175
nrf_gpio_port_write (NRF_GPIO_PORT_SELECT_PORT1, strobe_mask | 0x1F );
180
176
181
177
// Move on to the next row.
182
178
strobe_mask <<= 1 ;
183
179
strobe_row++;
184
180
185
- // reset the row counts and bit mask when we have hit the max.
186
- if (strobe_row == MICROBIT_DISPLAY_ROW_COUNT) {
181
+ // Reset the row counts and bit mask when we have hit the max.
182
+ if (strobe_row == MICROBIT_DISPLAY_ROW_COUNT) {
187
183
strobe_row = 0 ;
188
184
strobe_mask = 0x20 ;
189
185
}
190
186
191
- // prepare row for rendering
192
- for (int i = 0 ; i<MICROBIT_DISPLAY_COLUMN_COUNT; i++)
193
- {
187
+ // Prepare row for rendering.
188
+ for (int i = 0 ; i < MICROBIT_DISPLAY_COLUMN_COUNT; i++) {
194
189
int x = display_map[i][strobe_row].x ;
195
190
int y = display_map[i][strobe_row].y ;
196
-
197
191
row_brightness[i] = microbit_display_obj.image_buffer [x][y];
198
192
}
199
- /* Turn on any pixels that are at max */
193
+ // Turn on any pixels that are at max.
200
194
setPinsForRow (MAX_BRIGHTNESS);
201
-
202
195
}
203
196
204
- static const uint16_t render_timings[] =
197
+ static const uint16_t render_timings[] =
205
198
// The timer precision is only about 32us, so these timing will be rounded.
206
199
// The scale is exponential, each step is approx x1.9 greater than the previous.
207
200
{ 0 , // Brightness, Duration (approx)
208
201
35 , // 1, 35
209
- 32 , // 2, 67
210
- 61 , // 3, 128
211
- 115 , // 4, 243
212
- 219 , // 5, 462
213
- 417 , // 6, 879
214
- 791 , // 7, 1670
215
- 1500 , // 8, 3170
202
+ 32 , // 2, 67
203
+ 61 , // 3, 128
204
+ 115 , // 4, 243
205
+ 219 , // 5, 462
206
+ 417 , // 6, 879
207
+ 791 , // 7, 1670
208
+ 1500 , // 8, 3170
216
209
// Always on 9, ~6000
217
210
};
218
-
219
211
220
- /* * Egregious hack to work around paranoia in the DAL API.
221
- */
212
+
213
+ // Egregious hack to work around paranoia in the DAL API.
222
214
struct FakeMicroBitDisplay : public MicroBitComponent
223
215
{
224
216
uint8_t width;
@@ -239,19 +231,20 @@ Timeout *renderTimer = &((FakeMicroBitDisplay*)(&(uBit.display)))->renderTimer;
239
231
void microbit_display_obj_t::renderRow () {
240
232
mp_uint_t brightness = previous_brightness+1 ;
241
233
setPinsForRow (brightness);
242
- if (brightness == MAX_BRIGHTNESS)
234
+ if (brightness == MAX_BRIGHTNESS) {
243
235
return ;
236
+ }
244
237
previous_brightness = brightness;
245
- // Attach to timer
238
+ // Attach this function to the timer.
246
239
renderTimer->attach_us (this , µbit_display_obj_t ::renderRow, render_timings[brightness]);
247
-
248
240
}
249
241
250
242
251
243
static void microbit_display_update (void ) {
252
244
async_tick += FIBER_TICK_PERIOD_MS;
253
- if (async_tick < async_delay)
245
+ if (async_tick < async_delay) {
254
246
return ;
247
+ }
255
248
async_tick = 0 ;
256
249
switch (async_mode) {
257
250
case ASYNC_MODE_ANIMATION:
@@ -261,7 +254,7 @@ static void microbit_display_update(void) {
261
254
}
262
255
microbit_display_obj_t *display = (microbit_display_obj_t *)MP_STATE_PORT (async_data)[0 ];
263
256
/* WARNING: We are executing in an interrupt handler.
264
- * If an exception is raised here, then a reset is the only way to recover */
257
+ * If an exception is raised here, then a reset is the only way to recover. */
265
258
mp_obj_t obj = mp_iternext (async_iterator);
266
259
if (obj == MP_OBJ_STOP_ITERATION) {
267
260
if (async_repeat_iterable) {
@@ -299,7 +292,7 @@ static void microbit_display_update(void) {
299
292
void microbit_display_tick (void ) {
300
293
301
294
microbit_display_obj.advanceRow ();
302
-
295
+
303
296
microbit_display_update ();
304
297
microbit_display_obj.previous_brightness = 0 ;
305
298
if (microbit_display_obj.brightnesses & GREYSCALE_MASK) {
@@ -308,7 +301,7 @@ void microbit_display_tick(void) {
308
301
}
309
302
310
303
void microbit_display_animate (microbit_display_obj_t *self, mp_obj_t iterable, mp_int_t delay, bool wait, bool loop) {
311
- // reset repeat state
304
+ // Reset the repeat state.
312
305
MP_STATE_PORT (async_data)[0 ] = NULL ;
313
306
MP_STATE_PORT (async_data)[1 ] = NULL ;
314
307
MP_STATE_PORT (async_data)[2 ] = NULL ;
@@ -337,22 +330,23 @@ STATIC mp_obj_t microbit_display_animate_func(mp_uint_t n_args, const mp_obj_t *
337
330
{ MP_QSTR_loop, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false } },
338
331
};
339
332
340
- // parse args
333
+ // Parse the args.
341
334
microbit_display_obj_t *self = (microbit_display_obj_t *)pos_args[0 ];
342
335
mp_arg_val_t args[MP_ARRAY_SIZE (animate_allowed_args)];
343
336
mp_arg_parse_all (n_args - 1 , pos_args + 1 , kw_args, MP_ARRAY_SIZE (animate_allowed_args), animate_allowed_args, args);
344
-
337
+
345
338
mp_obj_t arg0 = args[0 ].u_obj ;
346
339
mp_int_t stride = args[2 ].u_int ;
347
340
mp_int_t start = args[3 ].u_int ;
348
341
mp_obj_t iterable;
349
342
if (mp_obj_get_type (arg0) == µbit_image_type) {
350
- iterable = microbit_image_slice ((microbit_image_obj_t *)arg0, start, /* width*/ 5 , stride);
343
+ // Convert single image into an iterable of images.
344
+ iterable = microbit_image_slice ((microbit_image_obj_t *)arg0, start, 5 /* width*/ , stride);
351
345
} else {
352
346
iterable = arg0;
353
347
}
354
348
355
- microbit_display_animate (self, iterable, args[1 ].u_int /* delay*/ , args[4 ].u_bool /* wait? */ , args[5 ].u_bool /* loop?*/ );
349
+ microbit_display_animate (self, iterable, args[1 ].u_int /* delay*/ , args[4 ].u_bool /* wait?*/ , args[5 ].u_bool /* loop?*/ );
356
350
return mp_const_none;
357
351
}
358
352
MP_DEFINE_CONST_FUN_OBJ_KW (microbit_display_animate_obj, 2 , microbit_display_animate_func);
@@ -370,20 +364,20 @@ mp_obj_t microbit_display_scroll_func(mp_uint_t n_args, const mp_obj_t *pos_args
370
364
{ MP_QSTR_wait, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true } },
371
365
{ MP_QSTR_loop, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false } },
372
366
};
373
- // parse args
367
+ // Parse the args.
374
368
microbit_display_obj_t *self = (microbit_display_obj_t *)pos_args[0 ];
375
369
mp_arg_val_t args[MP_ARRAY_SIZE (scroll_allowed_args)];
376
370
mp_arg_parse_all (n_args - 1 , pos_args + 1 , kw_args, MP_ARRAY_SIZE (scroll_allowed_args), scroll_allowed_args, args);
377
371
mp_uint_t len;
378
372
const char * str = mp_obj_str_get_data (args[0 ].u_obj , &len);
379
373
mp_obj_t iterable = scrolling_string_image_iterable (str, len, args[0 ].u_obj );
380
- microbit_display_animate (self, iterable, args[1 ].u_int /* delay*/ , args[2 ].u_bool /* wait?*/ , args[3 ].u_bool /* loop?*/ );
374
+ microbit_display_animate (self, iterable, args[1 ].u_int /* delay*/ , args[2 ].u_bool /* wait?*/ , args[3 ].u_bool /* loop?*/ );
381
375
return mp_const_none;
382
376
}
383
377
MP_DEFINE_CONST_FUN_OBJ_KW (microbit_display_scroll_obj, 1 , microbit_display_scroll_func);
384
378
385
379
void microbit_display_clear (void ) {
386
- // reset repeat state, cancel animation and clear screen
380
+ // Reset repeat state, cancel animation and clear screen.
387
381
async_mode = ASYNC_MODE_CLEAR;
388
382
async_tick = async_delay - FIBER_TICK_PERIOD_MS;
389
383
wait_for_event ();
@@ -396,10 +390,12 @@ mp_obj_t microbit_display_clear_func(void) {
396
390
MP_DEFINE_CONST_FUN_OBJ_1 (microbit_display_clear_obj, microbit_display_clear_func);
397
391
398
392
void microbit_display_set_pixel (microbit_display_obj_t *display, mp_int_t x, mp_int_t y, mp_int_t bright) {
399
- if (x < 0 || y < 0 || x > 4 || y > 4 )
393
+ if (x < 0 || y < 0 || x > 4 || y > 4 ) {
400
394
nlr_raise (mp_obj_new_exception_msg (&mp_type_ValueError, " index out of bounds." ));
401
- if (bright < 0 || bright > MAX_BRIGHTNESS)
395
+ }
396
+ if (bright < 0 || bright > MAX_BRIGHTNESS) {
402
397
nlr_raise (mp_obj_new_exception_msg (&mp_type_ValueError, " brightness out of bounds." ));
398
+ }
403
399
display->image_buffer [x][y] = bright;
404
400
display->brightnesses |= (1 << bright);
405
401
}
@@ -413,8 +409,9 @@ STATIC mp_obj_t microbit_display_set_pixel_func(mp_uint_t n_args, const mp_obj_t
413
409
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN (microbit_display_set_pixel_obj, 4 , 4 , microbit_display_set_pixel_func);
414
410
415
411
mp_int_t microbit_display_get_pixel (microbit_display_obj_t *display, mp_int_t x, mp_int_t y) {
416
- if (x < 0 || y < 0 || x > 4 || y > 4 )
412
+ if (x < 0 || y < 0 || x > 4 || y > 4 ) {
417
413
nlr_raise (mp_obj_new_exception_msg (&mp_type_ValueError, " index out of bounds." ));
414
+ }
418
415
return display->image_buffer [x][y];
419
416
}
420
417
@@ -425,7 +422,7 @@ STATIC mp_obj_t microbit_display_get_pixel_func(mp_obj_t self_in, mp_obj_t x_in,
425
422
MP_DEFINE_CONST_FUN_OBJ_3 (microbit_display_get_pixel_obj, microbit_display_get_pixel_func);
426
423
427
424
STATIC const mp_map_elem_t microbit_display_locals_dict_table[] = {
428
-
425
+
429
426
{ MP_OBJ_NEW_QSTR (MP_QSTR_get_pixel), (mp_obj_t )µbit_display_get_pixel_obj },
430
427
{ MP_OBJ_NEW_QSTR (MP_QSTR_set_pixel), (mp_obj_t )µbit_display_set_pixel_obj },
431
428
{ MP_OBJ_NEW_QSTR (MP_QSTR_print), (mp_obj_t )µbit_display_print_obj },
@@ -465,19 +462,19 @@ microbit_display_obj_t microbit_display_obj = {
465
462
};
466
463
467
464
static void ticker (void ) {
468
- /* Make sure we call the DAL ticker function */
465
+ // Make sure we call the DAL ticker function.
469
466
uBit.systemTick ();
470
- /* Update display */
467
+ // Update the display.
471
468
microbit_display_tick ();
472
469
}
473
470
474
471
void microbit_display_init (void ) {
475
- // set pins as output
472
+ // Set pins as output.
476
473
nrf_gpio_range_cfg_output (MICROBIT_DISPLAY_COLUMN_START,MICROBIT_DISPLAY_COLUMN_START + MICROBIT_DISPLAY_COLUMN_COUNT + MICROBIT_DISPLAY_ROW_COUNT);
477
-
474
+
478
475
uBit.display .disable ();
479
-
480
- /* Hijack the DAL system ticker */
476
+
477
+ // Hijack the DAL system ticker.
481
478
uBit.systemTicker .attach (ticker, MICROBIT_DISPLAY_REFRESH_PERIOD);
482
479
}
483
480
0 commit comments